在C中逐行读取管道

bla*_*pit 8 c stdin stdout pipe

如何分离来自管道的线.在管道中有这样的文字:

HALLO:500\n
TEST:300\N
ADAD
ADAWFFA
AFAGAGAEG
Run Code Online (Sandbox Code Playgroud)

我想将管道与管道分开,因为我想将值保存在变量中.

这是我的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);
}
Run Code Online (Sandbox Code Playgroud)

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

lus*_*oog 15

这通常只是从stdin读取.程序不应该关心输入是管道,重定向文件还是键盘.

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;
}
Run Code Online (Sandbox Code Playgroud)

这可以帮助您免受可怕的缓冲区溢出问题的影响.fgets不会写超过传递给它的大小.如上所述,另一半正在对可能由于意外长输入线导致的可能的部分线做一些合理的事情.