I’m writing a small C program that must accept an input stream larger than 4096 bytes.
I did find a post that recommended using setvbuf() here:
Making fgets issue longer read() calls on linux
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
Thanks!
Right now you're using _IONBF
, which means no buffering. Using _IOFBF
instead would probably be a good start (that's full buffering). 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. 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. As such, I generally consider setvbuf
as useless, albeit probably harmless, micro-optimization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With