首页 > 解决方案 > c中的char数组在溢出的scanf操作中

问题描述

我是 C 编程新手,我对以下代码感到非常困惑:

#include <stdio.h>
#include <string.h>
int main(void)
{
    char arrstr[6];
    int i;
    printf("Enter: ");
    scanf("%s",arrstr);
    printf("arrstr is %s\n",arrstr);
    printf("length os arrstr is %d\n",strlen(arrstr));
    for(i=0;i<20;i++)
    {
         printf("arrstr[%d] is %c, dec value is %d\n",i,arrstr[i],arrstr[i]);
    }
    return 0;
 }   

据我了解,在arrstr[6]声明之后,编译器会为这个char数组分配6个字节,考虑最后一个'\0'字符,可以在char数组中存储5个有效字符。

但是在我运行这个短代码之后,我得到以下结果: 在此处输入图像描述

printf 显示我输入的所有字符,无论它有多长。但是当我使用索引来检查数组时,似乎我无法在数组中找到额外的字符。

谁能帮忙解释发生了什么?

谢谢。

标签: scanf

解决方案


尝试通过在 scanf 语句之后添加此行来更改您的代码:

arrstr[5] = '\0';

发生的事情是用户条目覆盖了空字符。手动放回空字符可以为接下来的两行 printf 语句提供正确的行为。for 循环是另一回事。C 没有任何类型的边界检查,因此由程序员决定不要超出数组的边界。之后获得的值可能是任何值,因为此时您只是在读取未初始化的 RAM 字节。避免这种情况的标准方法是使用 const int 变量来声明数组大小:

const int SIZE = 6;
char arrstring[SIZE];

然后在 for 循环中也使用 SIZE 作为限制。

PS这里的用户输入仍然存在问题,因为理论上用户可以输入数百个字符,并且看起来会越界写入,可能会导致奇怪的错误。有一些方法可以限制用户条目的数量,但它相当复杂,这里有一些关于该主题的 stackoverflow 帖子。请记住以供将来参考:

使用 fgets 而不是 scanf 限制用户进入

使用 fgets 后清理标准输入流


推荐阅读