0

我正在尝试重写wc -l显示部分结果的副本,因为它接收输入(例如,

我当前的版本很简单

    while(!feof(in) &&
            //(readc=fread(buf, 1,BUFSIZE,in))) {
            (readc=read(0,buf, BUFSIZE))) {
            for(i=0;i<readc;i++) {
                    lines += (buf[i] == '\n');
            }
    }

问题是我stdin的仍然被块缓冲。这个练习的重点是让输出不必等待每个 4KB 块填满。我想行缓冲会很好。

示例应用:find | partial_wc

awk 'NR%1000==0 {printf "%d\r",NR} END {print NR}'有类似的输出,除了我想选择基于时间(例如每 1 秒)而不是行输出。此外,这是一个有趣的学习问题。

我尝试接受在为什么 grep 快速中给出的建议,但无法弄清楚要使用哪组系统调用。

4

2 回答 2

3

当然,试试 POSIX 终端控制 API:

#include <termios.h>

struct termios ctrl;
tcgetattr(STDIN_FILENO, &ctrl);
ctrl.c_lflag &= ~ICANON; // turning off canonical mode makes input unbuffered
tcsetattr(STDIN_FILENO, TCSANOW, &ctrl);
于 2013-07-25T03:55:01.730 回答
2

问题不在于您的标准输入被块缓冲,问题在于生成数据的进程的标准输出被块缓冲。如果您正在控制数据管道的整个进程链,您可以使用它unbuffer来解决这个问题,但在一般情况下,您的程序无法更改管道中前一个程序的输出流的缓冲。

于 2013-07-25T04:29:10.313 回答