简体   繁体   English

将 setvbuf() 与 STDIN stream 一起使用

[英]Using setvbuf() with STDIN stream

I'm writing a small C program that must accept an input stream larger than 4096 bytes.我正在编写一个小型 C 程序,该程序必须接受大于 4096 字节的输入 stream。

I did find a post that recommended using setvbuf() here:我确实在这里找到了推荐使用setvbuf()的帖子:

Making fgets issue longer read() calls on linux使 fgets 在 linux 上发出更长的 read() 调用

I'm still having a really hard time getting this to work – here's the bit of my code that I'm struggling with:我仍然很难让它工作 - 这是我正在努力解决的代码:

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 );
} 

Has anyone had success increasing this input buffer?有没有人成功增加了这个输入缓冲区?

My environment: Ubuntu 10.10 with the build-essential package我的环境:Ubuntu 10.10 与构建必需的 package

Thanks!谢谢!

Right now you're using _IONBF , which means no buffering.现在您正在使用_IONBF ,这意味着没有缓冲。 Using _IOFBF instead would probably be a good start (that's full buffering).改用_IOFBF可能是一个好的开始(即完全缓冲)。 To increase the buffer size, you'll also want to specify that large buffer size as the fourth parameter, something like:要增加缓冲区大小,您还需要将大缓冲区大小指定为第四个参数,例如:

setvbuf(stdin, NULL, _IOFBF, 16384);

This allocates the buffer space dynamically.这会动态分配缓冲区空间。 Depending on the situation, you might want to pass it the buffer instead:根据情况,您可能希望将缓冲区传递给它:

char mybuffer[32768];

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

I have experimented with buffer sizes in the past, and found little benefit in increasing it.我过去曾尝试过缓冲区大小,但发现增加它没有什么好处。 If you're using any higher-level input functions like fgets (or worse, fgetc or fscanf ), enough time will be spent searching for delimiters or in function call or parsing overhead that the number of read syscalls really doesn't matter that much, as long as the buffer is at least 1kb or so.如果您使用任何更高级别的输入函数,如fgets (或更糟的是fgetcfscanf ),则将花费足够的时间来搜索分隔符或在 function 调用或解析开销中read系统调用的数量实际上并不重要,只要缓冲区至少为 1kb 左右。 If on the other hand you're reading large blocks at a time (via fread ), the implementation should be smart enough to skip buffering entirely and read directly into the buffer provided by the caller.另一方面,如果您一次读取大块(通过fread ),则实现应该足够聪明,可以完全跳过缓冲并直接读入调用者提供的缓冲区。 As such, I generally consider setvbuf as useless, albeit probably harmless, micro-optimization.因此,我通常认为setvbuf是无用的,尽管可能是无害的微优化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM