2

我写了这个小程序来练习数组,它应该最多包含 10 个字符,结尾是 \0。它有效,但效果太好了,即使我输入了 50 个字符的名称,它也会输出正确的输入。是什么赋予了?

#include <stdio.h>


int main(int argc, char const *argv[])
{
char name[11];

printf("Enter your name: ");
scanf("%s", name);

printf("Hi, %s\n", name);   
return 0;
}
4

2 回答 2

8

您正在覆盖您分配的数组的末尾 - 您需要在 scanf 中指定要读取的字符串的长度以确保它适合。

scanf("%10s", name);

对代码的改进是生成格式字符串,使其始终具有正确的大小。

#include <stdio.h>


int main(int argc, char const *argv[])
{
char name[11];
char formatstr[50];

snprintf(formatstr, sizeof(formatstr), "%%%ds", sizeof(name)-1);

printf("Enter your name: ");
scanf(formatstr, name);

printf("Hi, %s\n", name);
return 0;
}
于 2012-08-28T00:47:45.533 回答
1

当你在C中分配一个数组时,你只是得到一块内存的起始内存地址,保证可以免费使用,仅此而已。此保证是基于您不会使用此数组来读取/写入其边界之外的任何内存位置的假设,而您只是这样做了!

当您尝试访问数组边界之外的内存位置时,JavaC#等高级语言将引发异常(错误),不幸的是,在C中您只能靠自己。

尽管您的示例似乎无害,但这种访问冲突是软件开发中的常见错误,可能会导致简单的故障到意外的堆栈溢出

于 2012-08-28T01:03:44.580 回答