下面简单的代码。 Mac OS X 10.10.5,Xcode 7.2,C文件。 如果我输入1,然后qwert,我得到0并返回qwert。 1和qwer给1和qwer。 1和1 qwerty给出121和qwerty。
#include <stdio.h>
int main() {
int userInput;
char q[5];
printf("Hello\n");
scanf("%d", &userInput);
printf("%d\nAnd\n", userInput);
scanf("%s", q);
printf("\n");
printf("%d\n%s", userInput, q);
return 0;
}
答案 0 :(得分:3)
我错过了什么?为什么我可以为5个char变量写超过4个字符(+ null)?
没有什么可以阻止你访问c
中数组的边界部分。这将编译:
char a[2];
a[10000] = 10;
为什么整数受影响?
导致的问题是undefined behavior,可能是您的int
受到影响的原因。您可以阅读c arrays
了解有关此内容的更多信息。这种情况正在发生,因为您将一个5个字符的字符串加上一个空终止字符(即6 chars
)放入一个仅用于5的空间。您将超出数组的范围。
另外请注意,scanf("%s"
没有提供防止此行为的方法。如果用户输入的字符串太长则太糟糕。这就是为什么你应该使用格式字符串"%4s"
或使用fgets
来保护你的输入:
fgets(q, sizeof q, stdin);
这两种方法都可以保护您的输入不会输入超过4个字符。
答案 1 :(得分:3)
[编辑]用户/代码可以尝试将超过4个字符(+ null)写入5个char变量&#34;。 C没有指定当代码不阻止此类事件时应该发生什么。 C没有安全网/训练轮编码。
scanf("%s", q);
读取并保存"qwert"
和的5个字符,它还会附加空字符'\0'
。 @Weather Vane
由于q[]
只有5个字符的空间,因此会出现未定义的行为(UB)。在OP的情况下,它似乎覆盖了userInput
。
要避免,请在"%s"
上使用宽度限制,如下所示。用户不会消耗4个以上的非空白区域。不幸的是,额外的文字将保留在stdin
。
char q[5];
scanf("%4s", q);
或者更好的是,请查看fgets()
以阅读用户输入。
答案 2 :(得分:0)
int userInput受影响的原因是您正在写入char数组的末尾(q)。由于这两个都是堆栈变量,你正在使用的编译器似乎是以“逆序”为堆栈分配局部变量的内存,它们按照定义的顺序被“推”,所以第一个局部变量列出的是堆栈中较低的。因此,在您的情况下,当您在q的末尾写入时,您正在为userInput分配的内存空间中写入,这就是它受影响的原因。