管道中的分段故障

时间:2012-02-17 13:17:57

标签: c linux segmentation-fault stdio

鉴于以下计划:

#include <stdio.h>

int main()
{
    char buf[1024];
    scanf("%s", buf);
    printf("----> %s", buf);
    return 0;
}

执行如下:

grep ....| a.out

echo ....| a.out

我收到Segmentation fault错误。任何人都可以解释原因吗?

3 个答案:

答案 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/^/----> '

无需编写自己的工具来完成工作。事实上,对于sedawk等等,您可能从不需要自己编写文本处理工具。

答案 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;
}