将5个字符写入char [5]会影响int

时间:2015-12-22 21:31:09

标签: c char int printf scanf

下面简单的代码。 Mac OS X 10.10.5,Xcode 7.2,C文件。 如果我输入1,然后qwert,我得到0并返回qwert。 1和qwer给1和qwer。 1和1 qwerty给出121和qwerty。

  • 我错过了什么 - 为什么我可以为5个char变量写超过4个字符(+ null)?
  • 为什么影响整数?
#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;
}

3 个答案:

答案 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分配的内存空间中写入,这就是它受影响的原因。