c-管道分段故障



给定以下程序:

#include <stdio.h>
int main()
{
    char buf[1024];
    scanf("%s", buf);
    printf("----> %s", buf);
    return 0;
}

其执行如下:

grep ....| a.out

echo ....| a.out

我收到一个Segmentation fault错误。有人能解释一下原因吗?

无论您要回显或重传的内容都必须包含1023个以上的字符。(1024-1表示空终止符。)

不要使用scanf,而是使用fgets并指定大小。或者,使用scanf,但指定字段长度。你可以做scanf("%1023s", buf);。如果有更多的字节可用,你总是可以再次读取其余的字节

考虑到您的测试输入,您不应该收到segfault。我只是在当地试了一下,效果很好。如果您在Linux上,由于您编写的是a.out而不是./a.out,根据路径的配置方式,您可能运行了错误的程序(bin文件夹中的某种a.out?)

永远不要将scanf与无界字符串一起使用。fgets提供了一个更安全的替代方案,特别是如果您提供了像本答案中那样的智能包装器函数。

我假设这只是这里的示例代码,但如果不是,您可以使用实现相同的效果

WhateverYourCommandIs | sed 's/^/----> '

而不必编写自己的工具来完成这项工作。事实上,使用sedawk等,您可能永远不需要自己编写文本处理工具。

来自scanf-man:
s匹配非空白字符序列;下一个指针必须是指向字符数组的指针,该数组的长度足以容纳输入序列和自动添加的终止null字符("\0")。输入字符串停止在空白处或最大字段宽度处,以先出现的为准。

指定最大字段宽度将防止堆栈溢出

    scanf("%1023s", buf);

为了确保打印时堆栈不会溢出,请使用memset:

    memset(buf,0,1024);

因此,程序将是:

#include <stdio.h>
#include <string.h>
int main()
{
    char buf[1024];
    memset(buf,0,1024);
    scanf("%1023s", buf);
    printf("----> %s", buf);
    return 0;
}

最新更新