0

我在 C 中的一些代码有问题:

char opt, name[10], path[25];
printf("Things\nMore things\n");
printf("Even more things\n");
printf("\nChar: ");
scanf("\n%c",&opt);
printf("\nTask name: ");
scanf("%s",name);
printf("Name: %s\n", name);
printf("\nFolder name: ");
scanf("%s",path);
printf("Name: %s\n", name);
printf("Path: %s\n", path);

这是在“干净”模式下制造麻烦的代码。问题是,当数据大小大于 10 或 25 时,它不会切割字符串,而是混合“名称”和“路径”。在某些情况下,它甚至将“路径”的一部分放入“名称”中。这是未定义的行为,还是我遗漏了什么?

4

7 回答 7

2

如果您想将用户输入限制为确切数量的字符,请尝试

scanf("%24s",path);

它应该防止您的 char 数组的缓冲区重载。

于 2013-05-29T13:14:54.267 回答
2

您需要告诉scanf输入字符串可以占用多少字节。您还需要告诉scanf丢弃所有输入直到行尾。由于您的提示不以换行符结尾,因此您应该刷新输出。

printf("\nChar: ");
fflush(stdout);
scanf("\n%c%*[^\n] ",&opt);
printf("\nTask name: ");
fflush(stdout);
scanf(" %9[^\n]%*[^\n] ", name);
printf("\nFolder name: ");
fflush(stdout);
scanf(" %24[^\n]%*[^\n] ", path);
于 2013-05-29T13:20:39.720 回答
1

scanf 不知道变量的大小(尤其是字符串变量)。它只是将字节放入内存空间,您必须自己检查是否有溢出。

由于数据结构对齐,没有段错误。

于 2013-05-29T13:16:20.307 回答
1

当您尝试将超过 10 个字符name 和超过 25 个字符写入path.

在这种特殊情况下,nameandpath被分配在堆栈上并且pathname. 但是由于堆栈是自上而下的,如果您在其中写入更多内容,则path可能会写入name.

阅读维基百科缓冲区溢出

于 2013-05-29T13:13:13.270 回答
1

如果您不想有任何问题,请将您scanf的字符串替换为:

fgets(name, 10, stdin);

其中第二个参数是数组的大小。这样,即使您尝试编写更多字符,它们也会被忽略。

于 2013-05-29T13:14:21.107 回答
0

您应该在使用 scanf 时指定要读取的最大大小以避免缓冲区溢出:

scanf("%10s", name);
于 2013-05-29T13:15:51.050 回答
0

它只是将名称重载到路径,因为它们占用彼此靠近的内存空间。

于 2013-05-29T13:12:12.673 回答