C循环没有破坏

时间:2017-11-02 07:33:23

标签: c pointers

我试图理解为什么以下程序以这种奇怪的方式行事。我声明了一个字符数组,并使用while循环和scanf输入字符。然而,当我输入字母或数字时,它似乎永远地运行。如果我输入一个大数字或一个字符串,它就会停止。为什么它不会在5次迭代后退出循环?

// This program runs forever if we input single-digit numbers
#include <stdio.h>

int main() 
{
    char u[5] = {0,};
    for (int i = 0; i<5; i++) {
        scanf(" %s", &u[i]);
    }
    printf("%s\n", u);
}

1 个答案:

答案 0 :(得分:4)

这无法修复。

scanf("%s", ...) 始终是一个严重的错误,因为您无法提前知道您的输入,%s匹配任何长度的任何非空白字符序列 - 有没有方式知道你的缓冲区必须有多大。

%s将从您传递的地址开始读取的字符作为参数写入。它会写一个额外的0字节作为字符串的结束标记。因此,使用您的代码,即使您只输入单个字符,最后一次迭代也会在0处写入u[5]字节超出范围,您的缓冲区溢出。

您甚至无法通过将%s更改为%c(与单个字符匹配)来修复它,因为您没有在数组末尾添加0字节,所以数组内容不是字符串,并将其传递给printf("%s", ...)再次是未定义的行为

重新开始,先读一本关于C的好书,当你完成后,最好忘记scanf()并使用更好的方法进行输入,如fgets()。另请参阅How to read / parse input in C? The FAQ和我的beginners' guide away from scanf()