C语言 在 C 中逐行读取管道
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16163154/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read from pipe line by line in C
提问by bladepit
How can I separate the lines which are coming from a pipe. In the pipe there is this text:
如何分离来自管道的线条。在管道中有这样的文字:
HALLO:500\n
TEST:300\N
ADAD
ADAWFFA
AFAGAGAEG
I want to separate the lines from the pipe because i want to save the values in variables.
我想将线条与管道分开,因为我想将值保存在变量中。
Here is my c code:
这是我的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);
}
Is this the right way to read from pipe for the best line by line?
这是从管道中逐行读取最佳方式的正确方法吗?
回答by luser droog
This is usually just called reading from stdin. The program shouldn't care whether the input is a pipe, a redirected file, or a keyboard.
这通常称为从 stdin 读取。程序不应该关心输入是管道、重定向文件还是键盘。
fread will just read until the buffer is full. Use fgets to read a line.
fread 将一直读取直到缓冲区已满。使用 fgets 读取一行。
Also the buffer size should be big enough to hold the line. For little one-off programs, you can just pick a number. Or there's a standard name BUFSIZwhich gives you a pretty-bigbuffer. How big? Big enough. Really? Probably.
此外,缓冲区大小应该足够大以容纳该行。对于一次性的小程序,您只需选择一个数字即可。或者有一个标准名称BUFSIZ可以为您提供相当大的缓冲区。多大?足够大。真的吗?大概。
fgetswill copy the newline character in the string unless the string fills up first. So you can test the last character to tell if the line was truncated or not. With reasonable inputs, that's not going to happen. But a more robust approach would allocate a larger buffer, copy the partial line, and call fgetsagain tp keep trying to get a complete line.
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;
}
This gets you halfway to being protected from the dreaded buffer overflowproblem. fgetswill not write more than the size passed to it. The other half, as mentioned above, is doing something sensible with the possible partial lines that may result from unexpectedly long input lines.
这使您免受可怕的缓冲区溢出问题的影响。fgets不会写入超过传递给它的大小。另一半,如上所述,正在对可能由意外长输入行导致的部分行做一些明智的事情。
回答by didinino
Here's another option (I am not totally sure it is a 'proper' way)- use the number of bytes read by the readfunction.
In this example I was reading from stdinalthough a redirection was made so the fd in 0 is a file/pipe/whatever you need it to be.
这是另一个选项(我不完全确定这是一种“正确”的方式)-使用read函数读取的字节数。在这个例子中,我正在阅读,stdin尽管做了重定向,所以 0 中的 fd 是一个文件/管道/任何你需要的东西。
while ((nbytes=read(STDIN_FILENO, buffer, MAX_PIPE_SIZE)) > 0) {
write(STDOUT_FILENO, buffer, nbytes);
}

