鉴于以下计划:
#include <stdio.h>
int main()
{
char buf[1024];
scanf("%s", buf);
printf("----> %s", buf);
return 0;
}
执行如下:
grep ....| a.out
或
echo ....| a.out
我收到Segmentation fault
错误。任何人都可以解释原因吗?
答案 0 :(得分:7)
无论您回音还是贪婪,必须包含超过1023个字符。 (对于空终止符,1024 - 1。)
使用scanf
并指定大小,而不是使用fgets
。或者,使用scanf
但指定字段长度。你可以做scanf("%1023s", buf);
。如果有更多字节可用,您可以再次执行此操作以阅读其余字节。
根据您的测试输入,您不应该收到段错误。我只是在本地尝试过,它工作正常。如果您使用的是Linux,那么由于您编写的是a.out
而不是./a.out
,因此根据路径的配置方式,您可能运行了错误的程序(bin文件夹中的某种a.out
? )
答案 1 :(得分:2)
不要将scanf
与无界字符串一起使用。 fgets
提供了一种更安全的替代方案,特别是如果您提供类似于this answer中的智能包装函数。
我假设这只是示例代码,但是,如果不是,您可以通过以下方式实现相同的效果:
WhateverYourCommandIs | sed 's/^/----> '
无需编写自己的工具来完成工作。事实上,对于sed
,awk
等等,您可能从不需要自己编写文本处理工具。
答案 2 :(得分:0)
来自scanf man:
s匹配一系列非空白字符;下一个指针必须是一个指向字符数组的指针,该指针足够长以容纳输入序列和终止空字符('\ 0'),这是自动添加的。输入字符串在空格或最大字段宽度处停止,以先到者为准。
指定最大字段宽度将防止堆栈溢出
scanf("%1023s", buf);
并确保printf上的堆栈没有溢出使用memset:
memset(buf,0,1024);
所以,programm将是:
#include <stdio.h>
#include <string.h>
int main()
{
char buf[1024];
memset(buf,0,1024);
scanf("%1023s", buf);
printf("----> %s", buf);
return 0;
}