c - 尽管 0 长度缓冲区和编译器警告,scanf() 仍然可以工作。到底是怎么回事?

标签 c string pointers scanf

我的编译器(clang)显示此消息:

11:17:warning: format specifies type 'char *' but the argument has
      type 'char (*)[0]' [-Wformat]
    scanf("%s", &name);
           ~~   ^~~~~
1 warning generated.

来自以下代码(问候程序):

/*
 * Program: gretting2.c
 * Utility: Display a greeting with your name.
 * Author:  Adrián Garro.
 */

#include <stdio.h>

int main () {

    char name[0];

    printf("-------------------\n");
    printf("Write your name: \n");
    printf("-------------------\n");

    scanf("%s", &name);

    printf("------------------------------------\n");
    printf("Hello %s, nice to meet you\n",name);
    printf("------------------------------------\n");
}

到底发生了什么,我该如何解决它?

最佳答案

为了理解这一点,您必须了解什么 scanf是在做。 scanf在本例中,是从标准输入读取字符串,并将其放入您提供的缓冲区中。 它不会为您分配该空间,也不会检测溢出。您需要为字符串分配足够的空间。就目前而言,您正在为字符串分配空间,因此一切都会溢出。这是一个重大错误。

说而不是 char[0] ,你做了char[40] ,正如另一位用户建议的那样。如果您的程序的用户写入了超过 40 个字符怎么办?这会导致未定义的行为。本质上,它会写入您不希望它写入的内存。它可能会导致段错误,可能会导致关键内存被覆盖,或者它可能会起作用。这是 scanf. 的弱点查看fgets.您告诉它缓冲区的大小,输入将被截断以适合。

当然,这与您的警告无关。您收到警告是因为引用数组的名称与引用指向其第一个元素的指针相同,即 name <==> &(name[0]) 。获取指向 this 的指针就像获取指向指针的指针,即 &name <==> &&(name[0]) 。自 scanf正在寻找 char* 类型的参数,并且它得到了一个指向它的指针,类型检查器提示道。

关于c - 尽管 0 长度缓冲区和编译器警告,scanf() 仍然可以工作。到底是怎么回事?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27789854/

相关文章:

c++ - 我们可以在 C++ 中重载 `==` 运算符来比较两个字符串吗?

将结构转换为成员类型的指针

c - 将 malloc 与函数和 strcmp 一起使用

c - 返回 C 中的字符指针数组

python - 在 python 中排序字符串不起作用

python - 获取列表中第一个字符串的第一个字符?

c++删除指针然后访问它指向的值

c++ - 如何将指针传递给对象方法?

c - 从单词中随机化字符

c - 在C中设置链表的交集和差集