I am trying to efficiently read from the stdin
by using setvbuf
in `_IOFBF~ mode. I am new to buffering. I am looking for working examples
I am going to recommend trying full buffering with setvbuf
and ditching fread
. If the specification is that there is one number per line, I will take that for granted, use fgets
to read in a full line and pass it to strtoul
parse the number that is supposed to be on that line.
#include
#include
#include
#include
#define INITIAL_BUFFER_SIZE 2 /* for testing */
int main(void) {
int n;
int divisor;
int answer = 0;
int current_buffer_size = INITIAL_BUFFER_SIZE;
char *line = malloc(current_buffer_size);
if ( line == NULL ) {
return EXIT_FAILURE;
}
setvbuf(stdin, (char*)NULL, _IOFBF, 0);
scanf("%d%d\n", &n, &divisor);
while ( n > 0 ) {
unsigned long dividend;
char *endp;
int offset = 0;
while ( fgets(line + offset, current_buffer_size, stdin) ) {
if ( line[strlen(line) - 1] == '\n' ) {
break;
}
else {
int new_buffer_size = 2 * current_buffer_size;
char *tmp = realloc(line, new_buffer_size);
if ( tmp ) {
line = tmp;
offset = current_buffer_size - 1;
current_buffer_size = new_buffer_size;
}
else {
break;
}
}
}
errno = 0;
dividend = strtoul(line, &endp, 10);
if ( !( (endp == line) || errno ) ) {
if ( dividend % divisor == 0 ) {
answer += 1;
}
}
n -= 1;
}
printf("%d\n", answer);
return 0;
}
I used a Perl script to generate 1,000,000 random integers between 0 and 1,000,000 and checked if they were divisible by 5 after compiling this program with gcc version 3.4.5 (mingw-vista special r3)
on my Windows XP laptop. The whole thing took less than 0.8 seconds.
When I turned buffering off using setvbuf(stdin, (char*)NULL, _IONBF, 0);
, the time went up to about 15 seconds.