如何在C中编写过滤程序?

pax*_*blo 9 c filter

由于UNIX拥有所有那些美妙的过滤器这样的程序(如grep,sed,tr等等),什么是写那些在标准C的一个最简单的方法是什么?

通过过滤器,我的意思是一个程序,它读取标准输入,执行一些数据操作,然后将其写入标准输出.这在构造命令管道时非常有用,每个命令都执行一些额外的数据操作,例如:

grep xyzzy input.file | tr '[A-Z]' '[a-z]' | sed 's/plugh/PLUGH/g'
Run Code Online (Sandbox Code Playgroud)

(每个|管道符号将前一个命令的标准输出连接到下一个命令的标准输入,因此是管道隐喻).

假设我需要一个将所有大写字符转换为小写的字符.而且,是的,我意识到这个特殊问题可以通过UNIX解决:

tr '[A-Z]' '[a-z]'
Run Code Online (Sandbox Code Playgroud)

但这只是一个例子.

我真正想要的是做这种过滤器的最简单的标准C源代码.

zmb*_*mbq 6

您可以getline像@ hroptatyr所描述的那样使用,但是您可以做一些更简单的事情:

#include <stdio.h>
#include <ctype.h>
int main(void) {
    int c;
    while ((c = getchar()) != EOF)
        putchar(tolower(c));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为有人应该真正解释关键点:过滤器是一个程序,它读取`stdin`对数据执行某些操作(可能包括无效操作,例如`cat`)并将转换后的数据写入`stdout`.当然,许多过滤器比这更多,例如,如果由选项指示,则读取/写入除`stdin` /`stdout`以外的文件.但我认为这是过滤器的核心概念. (3认同)

Fre*_*abe 5

“过滤器”程序只是一个从标准输入流(stdin)读取并写入标准输出流(stdout)的程序。在写入读取的数据之前,数据通常会以某种方式进行转换(如果您不执行任何转换或过滤,那么您基本上编写了一个cat程序,该程序仅打印出提供给它的任何内容)。过滤器程序的力量来自于这样一个事实:它们不决定输入来自哪里或输出去往哪里。相反,由程序的调用者提供输入/输出通道。

过滤器程序的核心可能如下所示(您可以使用它作为您自己的过滤器程序的模板):

#include <stdio.h>

int filter( FILE *input, FILE *output );

int main( void )
{
    const int retval = filter( stdin, stdout );
    fflush( stdout );
    return retval;
}
Run Code Online (Sandbox Code Playgroud)

就是这样。实际工作是由filter执行您想要的转换的函数完成的。例如,这是一个简单的程序,它从输入文件中读取字符,将它们转换为小写,然后将它们打印到输出文件:

#include <stdio.h>
#include <ctype.h> /* for tolower */

int filter( FILE *input, FILE *output )
{
    while ( !feof( input ) ) {
        if ( ferror( input ) ) {
            return 1;
        }
        fputc( tolower( fgetc( input ) ), output );
    }
    return 0;
}

int main( void )
{
    const int retval = filter( stdin, stdout );
    fflush( stdout );
    return retval;
}
Run Code Online (Sandbox Code Playgroud)

如果您编译并运行该程序,它只会坐在那里耐心等待从标准输入文件读取数据stdin。该文件通常绑定到控制台,这意味着您必须手动输入一些数据。但是,命令 shell 实现了一项称为管道的功能,该功能允许您将一个命令的输出通过管道传输到另一个命令的输入。这允许将多个程序组合到管道中以形成强大的命令。

以下是我们如何使用过滤器程序(假设您调用了生成的二进制文件lower):

$ echo Hello | lower
hello
$
Run Code Online (Sandbox Code Playgroud)

由于我们的过滤程序没有定义要读取的数据来自何处,因此我们可以将其与在stdout. 例如,以下是如何获取小写的整个文件(您可以type在 Windows 计算机上使用):

$ cat myfile.txt
Hello, World!
This is a simple test.

$ cat myfile.txt | lower
hello, world!
this is a simple test.

$
Run Code Online (Sandbox Code Playgroud)