I need to read an entire file. Past the \n all the wy to EOF. I am thinking about using unbuffered file reading(open) Is there another way.
I need to read an entire file. Past the \n all the wy to EOF. I am thinking about using unbuffered file reading(open) Is there another way.
What's in the file? How about using fgetc in a loop testing for EOF?
Demonographic rhinology is not the only possible outcome, but why take the chance
Using open() and read() are your best bet.
Oh god that would be horribly slow. Having to make a disk access call each time /shudderHow about using fgetc in a loop testing for EOF?
Just to play around I wrote a sample program for it
It will read a meg - 1 worth of data. -1 is the error code for read and 0 is the EOF code.Code:#include <stdio.h> #include <unistd.h> #include <fcntl.h> #define MEG 1048576 int main(void) { char buffer[MEG]; int fd, total=0, got=0; fd = open("file.txt", O_RDONLY); if ( fd == -1) { perror("Couldn't open file"); return 1; } while (total < sizeof(buffer) ) { got = read(fd, &buffer[total], sizeof(buffer) - total); if ( got == -1 ) { perror("Problem with read()"); break; } if ( got == 0) break; total += got; } printf("Got %d characters\n", total); printf("%s\n", buffer); return 0; }
Here's an idea (using standard C) for reading in an entire file,
note that error checking has been omitted.
Code:#include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { FILE* fp = fopen(argv[1], "rb"); char* buf; long nbytes; fseek(fp, 0L, SEEK_END); nbytes = ftell(fp); fseek(fp, 0L, SEEK_SET); /* restore file pointer indicator */ buf = malloc(nbytes * sizeof(char)); fread(buf, sizeof(char), nbytes, fp); fclose(fp); free(buf); return 0; }
Last edited by c99; 02-23-2004 at 03:34 PM.
Or maybe not.Originally posted by Thantos
Using open() and read() are your best bet.Oh god that would be horribly slow. Having to make a disk access call each time /shudderHow about using fgetc in a loop testing for EOF?
7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*
Good to know.
Of course reading one character at a time will still be slower then reading the entire block at once. For example I made a one meg file filled with random characters from ASCII value of 0 to 127. Ran the following two programs on it
entirefile.c
entirefile2.cCode:#include <stdio.h> #include <unistd.h> #include <fcntl.h> #define MEG 1048576 int main(void) { char buffer[MEG]; int fd, total=0, got=0; fd = open("file.txt", O_RDONLY); if ( fd == -1) { perror("Couldn't open file"); return 1; } while (total < sizeof(buffer) ) { got = read(fd, &buffer[total], sizeof(buffer) - total); if ( got <= 0) { if ( got == -1 ) { perror("Problem with read()"); break; } if ( got == 0) break; } total += got; } printf("Got %d characters\n", total); return 0; }
Times for entirefile.cCode:#include <stdio.h> #include <unistd.h> #include <fcntl.h> #define MEG 1048576 int main(void) { char buffer[MEG]; int total=0; FILE *fp; fp = fopen("file.txt", "r"); if ( fp == NULL) { perror("Couldn't open file"); return 1; } while (total < sizeof(buffer) ) { buffer[total]=fgetc(fp); if ( buffer[total] == EOF) { buffer[total]='\0'; break; } total++; } printf("Got %d characters\n", total); return 0; }
real 0m0.013s
user 0m0.000s
sys 0m0.010s
Times for entirefile2.c
real 0m0.115s
user 0m0.110s
sys 0m0.010s
Granted they are both under 1 second but stil fgetc was a little under 9 times slower.
Thantos, heh, I immediately went and did something simular.
I used time.h clock_t and clock() to get cpu ticks.
Results reading a 1MB file of random junk into a buffer:
fgetc took approx 731 cpu ticks.
fread took approx 20 cpu ticks.
That's almost 40X faster using fread to read in the entire file vs
reading in each byte separately.
... and you don't see a bug in this code?Code:buf = malloc(nbytes * sizeof(char)); fread(buf, sizeof(char), nbytes, fp); fclose(fp); printf("%s", buf)
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
Which one? The bug that assumes nbytes is really the size you want, the bug that results in a null pointer access if malloc fails or the bug that results in a null pointer access if fopen fails?... and you don't see a bug in this code?
nbyes will be the size of the file, as the file was opened in binary mode, so that isn't a bug. But still, you missed another one, keep guessingOriginally posted by Edward
Which one? The bug that assumes nbytes is really the size you want, the bug that results in a null pointer access if malloc fails or the bug that results in a null pointer access if fopen fails?
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
Edward, well done, you found three bugs that don't exist.
applause.
>>the bug that results in a null pointer access if malloc fails<<Originally posted by c99
Edward, well done, you found three bugs that don't exist.
applause.
That's valid.
>> or the bug that results in a null pointer access if fopen fails?<<
That's also valid.
OK, so we have to assume you omitted error checking for clarity purposes.
But, there's still another bug (a real bug, not an error checking problem)
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
True. But will the size of the file be the size that you expected?nbyes will be the size of the file
Not in your snippet unless I'm going blind (that I wear glasses suggests that this could very well be the case). However, in the original code there appears to be a & hiding where it shouldn't be that I missed in my first glance.But still, you missed another one
Really. Look again until you see at least two of them. I can tolerate the first because it isn't likely to be a problem.Edward, well done, you found three bugs that don't exist.
Am I the only one that doesn't wear glasses here? I could swearOk, so we have to assume you omitted error checking for clarity purposes.
the second line of my post says "note that error checking has
been omitted" or is this a case of selective blindness?
Which leaves the one bug which both Edward and I have yet to find.
Cat got your tongue?