将setvbuf()与STDIN流一起使用

时间:2011-05-03 22:17:00

标签: c stream stdin

我正在编写一个小型C程序,必须接受大于4096字节的输入流。

我确实在这里找到了推荐使用 setvbuf()的帖子:

Making fgets issue longer read() calls on linux

我仍然很难让这个工作 - 这是我正在努力解决的一些代码:

int main(void) 
{ 
#define MAX_STRING_SIZE 7168

char input_string[MAX_STRING_SIZE];

printf( "Input: " );

setvbuf( stdin, NULL, _IONBF, 0 );

fgets( input_string, MAX_STRING_SIZE-1, stdin );

printf( "\n" );
printf( "%s", input_string );
} 

有没有人成功增加这个输入缓冲区?

我的环境:带有build-essential软件包的Ubuntu 10.10

谢谢!

2 个答案:

答案 0 :(得分:4)

现在你正在使用_IONBF,这意味着没有缓冲。使用_IOFBF代替可能是一个好的开始(那是完整的缓冲)。要增加缓冲区大小,您还需要将大缓冲区大小指定为第四个参数,例如:

setvbuf(stdin, NULL, _IOFBF, 16384);

这会动态分配缓冲区空间。根据具体情况,您可能希望将缓冲区传递给它:

char mybuffer[32768];

setvbuf(stdin, mybuffer, _IOFBF, sizeof(mybuffer));

答案 1 :(得分:3)

我过去曾尝试使用缓冲区大小,并且发现增加它的好处不大。如果您正在使用任何更高级别的输入函数,例如fgets(或更糟,fgetcfscanf),则会花费足够的时间来搜索分隔符或函数调用或解析开销只要缓冲区至少为1kb左右,read系统调用的数量确实无关紧要。另一方面,如果你一次只读取大块(通过fread),那么实现应该足够智能以完全跳过缓冲并直接读入调用者提供的缓冲区。因此,我通常认为setvbuf是无用的,尽管可能是无害的微优化。