从管道读取线用C(Read from pipe line by line in C)

2019-08-31 21:34发布

我怎么能单独被从管道来的线。 在管有这样的文字:

HALLO:500\n
TEST:300\N
ADAD
ADAWFFA
AFAGAGAEG

我想是因为我要保存变量的值从管道的线分开。

这里是我的C代码:

#include <stdio.h>
#include <stdlib.h>

#define BUFFERSIZE    1

int main(int argc, char **argv){
    unsigned char     buffer[BUFFERSIZE];
    FILE                         *instream;
    int                            bytes_read=0;
    int                            buffer_size=0;


    buffer_size=sizeof(unsigned char)*BUFFERSIZE;
    /* open stdin for reading */
    instream=fopen("/dev/stdin","r");

    /* did it open? */
    if(instream!=NULL){
        /* read from stdin until it's end */
        while((bytes_read=fread(&buffer, buffer_size, 1, instream))==buffer_size){
            fprintf(stdout, "%c", buffer[0]);
        }
    }
    /* if any error occured, exit with an error message */
    else{
        fprintf(stderr, "ERROR opening stdin. aborting.\n");
        exit(1);
    }

    return(0);
}

这是从管道读通过线的最佳路线的正确方法?

Answer 1:

这通常就叫从标准输入读取 。 该方案不应该关心的输入是否是管道,重定向的文件,或键盘。

FREAD只会读,直到缓冲区已满。 用fgets读取一行。

此外缓冲区的大小应该是足够大压阵。 对于小一次性程序,你可以随便挑一个数字。 还是有一个标准名称BUFSIZ它给你一个漂亮的,大的缓冲区。 多大? 足够大。 真? 大概。

fgets除非字符串第一填满将字符串中复制换行符。 所以,你可以测试的最后一个字符来告诉我们,如果线被截断或没有。 以合理的投入,这是不会发生的。 但是,一个更强大的方式将分配一个更大的缓冲区,复制部分的线,并呼吁fgets再次TP不断尝试得到一个完整的线。

#include <stdio.h>

int main() {
    char buf[BUFSIZ];
    fgets(buf, sizeof buf, stdin);
    if (buf[strlen(buf)-1] == '\n') {
        // read full line
    } else {
        // line was truncated
    }
    return 0;
}

这可以让你中途的保护,可怕的缓冲区溢出问题。 fgets不会写超过传递给它的规模。 另一半中,如上所述,是做一些合理的与可能导致意外长输入线的可能局部线。



Answer 2:

这里的另一个选项(我不能完全肯定这是一个“正确”的方式) -使用由读取的字节数read功能。 在这个例子中,我从读stdin ,虽然重定向制成所以在0 fd是一个文件/管材/无论你需要它。

  while ((nbytes=read(STDIN_FILENO, buffer, MAX_PIPE_SIZE)) > 0) {
    write(STDOUT_FILENO, buffer, nbytes);
  }


文章来源: Read from pipe line by line in C