我正在阅读“黑客:剥削艺术”一书。我现在只在开头的章节中,它正在用C语言进行一些基本的字符串复制和输入功能。
最新的示例使用strcpy和scanf的组合来重复打印字符串,但在编译时,会为我生成格式错误的输出。示例如下:
Input.c中:
#include <stdio.h>
#include <string.h>
int main() {
char message[10];
int count, i;
strcpy(message, "Hello, world!");
printf("Repeat how many times? ");
scanf("%d", &count);
for(i=0; i < count; i++)
printf("%3d - %s\n", i, message);
}
根据这本书,当你输入一个数字时,它应该多次打印。
例如:
reader@hacking:~/booksrc $ ./input
Repeat how many times? 3
0 - Hello, world!
1 - Hello, world!
2 - Hello, world!
这适合我,但不知怎的,“Hello,world!”字符串变得损坏和格式错误,只打印“Hello,wor”,然后打印错误的字符。
helpme@stackoverflow:~/booksrc $ ./input
Repeat how many times? 3
0 - Hello, wor
1 - Hello, wor␦
2 - Hello, wor␦
最后打印的错误字符似乎有一些一致性,好像它是通过UTF-8字符或类似的东西进行迭代。对于前三个,它将打印表示不可打印的Unicode字符的框,如果给出更高的范围,最终将开始打印真实字符。
我认为这与使用scanf和我的终端有关(我在Debian GNU / Linux机器上运行这个程序,使用默认的GNOME终端。)但我很好奇这个例子可能有什么在以前版本的gcc上工作而不是当前版本 - scanf在当前版本的C上有不同的解释吗?
至于其他信息,我正在运行gcc版本6.3.0。
如果有人能提供任何帮助,我们将不胜感激。谢谢!
答案 0 :(得分:3)
char message[10];
...
strcpy(message, "Hello, world!");
message
不能包含整个Hello, world!
,因为它很小。因此,您将遇到未定义的行为,这解释了您所看到的奇怪输出。您需要增加message
的大小或动态确定其所需的大小,例如使用strlen
。
答案 1 :(得分:2)
您的问题是消息缓冲区的长度。字符串&#34; Hello,world!&#34;包含13个字符+ \0
,其中strcpy会自动添加,因此最终长度为14.以下是代码:
#include <stdio.h>
#include <string.h>
int main() {
char message[14];
int count, i;
strcpy(message, "Hello, world!");
printf("Repeat how many times? ");
scanf("%d", &count);
for(i=0; i < count; i++)
printf("%3d - %s\n", i, message);
}
提示:最好使用strnlen而不是strlen。
答案 2 :(得分:0)
echo "Hello, world!" | wc
1 2 14
所以你的字符串最后0
有14 + 1个字节,你试着将它保存在10个字节的数组中。
strcpy
会产生溢出。