Author |
Message |
David Corde #1 / 12
|
 How do I read past EOF
I have a series of files that contain ASCII character representations of intergers from 0 to 255. I need to read these files in order to do some data manipulations. Here's what I tried so far: #include <stdio.h> #include <stdlib.h> #define imax 32760 int main(void) { int c, i, num, csiq[imax]; FILE *ifp, *ofp; ifp = fopen("tstfil0.wav", "r"); ofp = fopen("ntstfil.dat", "w"); for (num = 0; num < imax+4; num++) { c = getc(ifp); if (num >= 4) csiq[num-4] = c; } // print array csiq to file as integers to check. for (i = 0; i < imax; i++) fprintf(ofp, "%6d%6d\n", i+1,csiq[i]); Quote: }
This works up to a point. For each file it's a different data point, but eventually the program stops reading and fills in the rest of my csiq array with the integer value -1. Which is suspiciously the same value that stdio.h has EOF set to. So, since I know that each file has exactly 32767 characters in them. And I want to read in the 5th through 32765th values and save them as integers. How do I get past the apparent EOF that I'm running into. At least I think it's EOF that I'm hitting. But I checked the 6 or so files and the integer that the last character read converted to is not consistant. Nor is the character that follows the last data point read. Any help greatly appreciated. The guy in the next cubical is tired of hearing my forehead slamming into the monitor. David --
|
Wed, 12 Sep 2001 03:00:00 GMT |
|
 |
Paul Jar #2 / 12
|
 How do I read past EOF
Quote:
> #include <stdio.h> > #include <stdlib.h> > #define imax 32760 > int main(void) > { > int c, i, num, csiq[imax];
I'm surprised this hasn't caused problems. Large objects like this array often don't work as automatic variables. Static and dynamic allocation are commonly used for such things. Quote: > FILE *ifp, *ofp; > ifp = fopen("tstfil0.wav", "r"); > ofp = fopen("ntstfil.dat", "w"); > for (num = 0; num < imax+4; num++) > { > c = getc(ifp); > if (num >= 4) > csiq[num-4] = c; > }
I doubt this is related to your problem, but I'd rewrite this as something like: for (num=0; num<4; ++num) getc(ifp); for (num=0; num<imax; ++num) csiq[num]=getc(ifp); It's a little clearer to me that way. If you're hitting EOF before the end of the file, I expect there's some sort of read error. Try: for (num=0; num<imax; ++num) if ((csiq[num]=getc(ifp))==EOF) { perror("Error reading file"); break; } Quote: > // print array csiq to file as integers to check. > for (i = 0; i < imax; i++) > fprintf(ofp, "%6d%6d\n", i+1,csiq[i]); > }
You've probably trimmed out lots of things from your actual program, but judging by what's here, you don't need the array at all. Unless your data manipulation requires examining more than one byte from the input file at a time, you could just do each byte individually: for (num=0; num<imax; ++num) { if ((c=getc(ifp))==EOF) { /* handle error */ } fprintf(ofp, "%6d%6d\n", num+1, c); } I'd also recommend explicitly closing your files. It's supposed to be done automatically when your programs exits, but if your C implementation is faulty, you'll have to do it yourself. HTH paul --
|
Fri, 14 Sep 2001 03:00:00 GMT |
|
 |
Jack Kle #3 / 12
|
 How do I read past EOF
On Sat, 27 Mar 1999 17:08:42 GMT, David Cordes
Quote: > I have a series of files that contain ASCII character representations > of intergers from 0 to 255. I need to read these files in order to do > some data manipulations. > Here's what I tried so far: > #include <stdio.h> > #include <stdlib.h> > #define imax 32760 > int main(void) > { > int c, i, num, csiq[imax]; > FILE *ifp, *ofp; > ifp = fopen("tstfil0.wav", "r"); > ofp = fopen("ntstfil.dat", "w"); > for (num = 0; num < imax+4; num++) > { > c = getc(ifp); > if (num >= 4) > csiq[num-4] = c; > } > // print array csiq to file as integers to check. > for (i = 0; i < imax; i++) > fprintf(ofp, "%6d%6d\n", i+1,csiq[i]); > } > This works up to a point. For each file it's a different data point, > but eventually the program stops reading and fills in the rest of > my csiq array with the integer value -1. Which is suspiciously the > same value that stdio.h has EOF set to. > So, since I know that each file has exactly 32767 characters in them. > And I want to read in the 5th through 32765th values and save them > as integers. How do I get past the apparent EOF that I'm running into. > At least I think it's EOF that I'm hitting. But I checked the 6 or so > files and the integer that the last character read converted to is not > consistant. Nor is the character that follows the last data point read. > Any help greatly appreciated. The guy in the next cubical is tired of > hearing my forehead slamming into the monitor. > David
<Jack> If your file contains binary data you must open it in binary mode, that is with "rb" or "wb" instead of just "r" or "b". If you do not specify binary mode the file is opened in text mode and the C language standard requires that certain translations be made between your program and the host operating systems's ordinary convention for text files. Since you are posting from a DOS/Windows host, you are most likely hitting a value of 0x1a in the file, otherwise known as Ctrl-Z, which is the DOS/Windows convention for EOF in a text file. You haven't seen this pattern because it has nothing to do with the last character read and successfully converted, but the character after that which was read and translated to EOF. Opening the file in binary mode will also prevent other common text conversion artifacts such as 0x0d ('\r') being skipped on input, and output of 0x0a ('\n') being converted to "\r\n". </Jack> -- Do not email me with questions about programming. Post them to the appropriate newsgroup. Followups to my posts are welcome. --
|
Fri, 14 Sep 2001 03:00:00 GMT |
|
 |
David Mitchel #4 / 12
|
 How do I read past EOF
This is also the binary value for -1. What I mean is 255 is : 1111 1111 in binary binary for -1 is also 1111 1111, so if you have a big long series of 255's in your file they might be read as -1. To fix this, don't use getc, try using fread or fgets or something that doesn't return an int (which BTW are by default signed) but instead returns a char or writes to a char buffer. This might not be quite as nice but it should stop your problem (assuming you have a hole heap of 255's in your file). Hope this helps David Mitchell. Quote:
> I have a series of files that contain ASCII character representations > of intergers from 0 to 255. I need to read these files in order to do > some data manipulations. > Here's what I tried so far: > #include <stdio.h> > #include <stdlib.h> > #define imax 32760 > int main(void) > { > int c, i, num, csiq[imax]; > FILE *ifp, *ofp; > ifp = fopen("tstfil0.wav", "r"); > ofp = fopen("ntstfil.dat", "w"); > for (num = 0; num < imax+4; num++) > { > c = getc(ifp); > if (num >= 4) > csiq[num-4] = c; > } > // print array csiq to file as integers to check. > for (i = 0; i < imax; i++) > fprintf(ofp, "%6d%6d\n", i+1,csiq[i]); > } > This works up to a point. For each file it's a different data point, > but eventually the program stops reading and fills in the rest of > my csiq array with the integer value -1. Which is suspiciously the > same value that stdio.h has EOF set to. > So, since I know that each file has exactly 32767 characters in them. > And I want to read in the 5th through 32765th values and save them > as integers. How do I get past the apparent EOF that I'm running into. > At least I think it's EOF that I'm hitting. But I checked the 6 or so > files and the integer that the last character read converted to is not > consistant. Nor is the character that follows the last data point read. > Any help greatly appreciated. The guy in the next cubical is tired of > hearing my forehead slamming into the monitor. > David > --
--
|
Fri, 14 Sep 2001 03:00:00 GMT |
|
 |
The z #5 / 12
|
 How do I read past EOF
im not sure why you would want to read past EOF, but there are couple of things to know. a) WAV files should be opened in binary mode ifp = fopen("tstfil0.wav", "rb"); All the characters in a WAV file are not between 0-255. im not sure what exactly you want to do w/ ntstfil.dat How do I get past the apparent EOF that I'm running into. J/ a for() loop should do it. The results are unpredictable though, which is probably why you are seeing the differant chars at the end. Also, use feof instread of eof,as eof is designed for ascii. Basicly, try opening the file in binary mode and using feof, and filter manually. hope this helps --
|
Fri, 14 Sep 2001 03:00:00 GMT |
|
 |
Kurt Watz #6 / 12
|
 How do I read past EOF
Quote:
>I have a series of files that contain ASCII character representations >of intergers from 0 to 255. I need to read these files in order to do >some data manipulations.
This sound suspiciously as if you want to read a file of binary bytes, at least to me. If this is indeed what you are after, reading the file in binary mode might be the best idea. Quote: >Here's what I tried so far: >#include <stdio.h> >#include <stdlib.h> >#define imax 32760
This is a suspicious number, but it might be completely unrelated to your problem. What do you plan to do about the missing eight whatshamicallem? Quote: >int main(void) >{ >int c, i, num, csiq[imax]; >FILE *ifp, *ofp; >ifp = fopen("tstfil0.wav", "r"); >ofp = fopen("ntstfil.dat", "w");
This more or less confirms my suspicion. If we are to accept that a .wav file is what the uninformed layman expects it to be, you really want to process those files as binary files, i.e., use "rb" instead of "r" as the second argument to fopen. If this is supposed to be more than a quick hack, you should consider _checking_ the return value of all calls to the standard C library that might result in calls to an underlying system that might fail. Even _if_ it is a quick hack, something like assert(ifp != NULL); assert(ofp != NULL); might be a good idea just after the call to fopen(). If you are sure that the call to fopen() can never fail, just say so loed an clear. Quote: >for (num = 0; num < imax+4; num++) > { > c = getc(ifp);
Whatever you really want to do, this is the point in your program that needs different treatment in most situations. In a quick hack, you might simply assert that c is not EOF, in a real program you would have to check against it and think about error handling. Quote: >So, since I know that each file has exactly 32767 characters in them. >And I want to read in the 5th through 32765th values and save them >as integers. How do I get past the apparent EOF that I'm running into.
In a halfway sane environment, opening the input file in binary mode should allow you to do what you want. Kurt -- | Kurt Watzka
--
|
Fri, 14 Sep 2001 03:00:00 GMT |
|
 |
Jan Echterna #7 / 12
|
 How do I read past EOF
Quote: > This is also the binary value for -1. What I mean is 255 is : 1111 1111 in > binary > binary for -1 is also 1111 1111, so if you have a big long series of 255's > in your file they might be read as -1. To fix this, don't use getc, try > using fread or fgets or something that doesn't return an int (which BTW are > by default signed) but instead returns a char or writes to a char buffer. > This might not be quite as nice but it should stop your problem (assuming > you have a hole heap of 255's in your file).
You're on the wrong path. getc() returns the character cast to an unsigned char and then cast to an int. Thus, if -1 is read from the file, it would be returned as 255 (on platforms with CHAR_BIT == 8). There is another problem, however. If INT_MAX < UCHAR_MAX, getc() may return values < 0. It may even return -1 for valid chars. Therefore, you have to always use feof() and ferror() if you want to write really portable programs. But you can still test for -1 as an optimization. This way you don't have to check for eof or error on each char. int c; c = getc (some_input); if (c == -1 && (feof (some_input) || ferror (some_input)) { /* EOF or error */ } -- Jan --
|
Fri, 14 Sep 2001 03:00:00 GMT |
|
 |
David Corde #8 / 12
|
 How do I read past EOF
Shortly after posting the message I 'discovered' opening files in binary mode with the "rb" setting. That solved my problems. Thanks for the advice anyway. I've used a few other suggestions for streamling my code that were included with some of the responses. DC Quote:
> I have a series of files that contain ASCII character representations > of intergers from 0 to 255. I need to read these files in order to do > some data manipulations. > Here's what I tried so far: > #include <stdio.h> > #include <stdlib.h> > #define imax 32760 > int main(void) > { > int c, i, num, csiq[imax]; > FILE *ifp, *ofp; > ifp = fopen("tstfil0.wav", "r"); > ofp = fopen("ntstfil.dat", "w"); > for (num = 0; num < imax+4; num++) > { > c = getc(ifp); > if (num >= 4) > csiq[num-4] = c; > } > // print array csiq to file as integers to check. > for (i = 0; i < imax; i++) > fprintf(ofp, "%6d%6d\n", i+1,csiq[i]); > } > This works up to a point. For each file it's a different data point, > but eventually the program stops reading and fills in the rest of > my csiq array with the integer value -1. Which is suspiciously the > same value that stdio.h has EOF set to. > So, since I know that each file has exactly 32767 characters in them. > And I want to read in the 5th through 32765th values and save them > as integers. How do I get past the apparent EOF that I'm running into. > At least I think it's EOF that I'm hitting. But I checked the 6 or so > files and the integer that the last character read converted to is not > consistant. Nor is the character that follows the last data point read. > Any help greatly appreciated. The guy in the next cubical is tired of > hearing my forehead slamming into the monitor. > David > --
--
|
Fri, 14 Sep 2001 03:00:00 GMT |
|
 |
Shagg #9 / 12
|
 How do I read past EOF
Groovy hepcat David Cordes was jivin' on Sat, 27 Mar 1999 17:08:42 GMT in comp.lang.c.moderated. How do I read past EOF's a cool scene! Dig it! Quote: >I have a series of files that contain ASCII character representations >of intergers from 0 to 255. I need to read these files in order to do >some data manipulations. >Here's what I tried so far: >#include <stdio.h> >#include <stdlib.h> >#define imax 32760 >int main(void) >{ >int c, i, num, csiq[imax];
csiq is an array of 32760 integers. This will be at least 65520 bytes, all (typically) allocated on the stack. That may not leave alot of room on the stack for other things. In fact, the stack is set to around 1k or 2k by default on my compiler. Your 65520 byte (in a 16 bit target, or 131040 bytes in 32 bit target) would blow the stack clean to Hell if I compiled it on my compiler. Quote: >FILE *ifp, *ofp; >ifp = fopen("tstfil0.wav", "r"); >ofp = fopen("ntstfil.dat", "w");
Are you sure these are ASCII files? (That's what you seemed to be saying above.) The .wav extension on one suggests a non-text file. Yet you open it in text mode. If the file is binary, certain characters will be interpreted by the system as control codes or the like, and you will get errors or invalid data. Also, you didn't check the returned pointers. What if a file could not be opened for some reason? Your program crashes, that's what. Quote: >for (num = 0; num < imax+4; num++)
What if there's some error reading the file? Your program will be recieving invalid data. Quote: > { > c = getc(ifp); > if (num >= 4) > csiq[num-4] = c; > } >// print array csiq to file as integers to check. >for (i = 0; i < imax; i++) >fprintf(ofp, "%6d%6d\n", i+1,csiq[i]);
I don't see a return value for main(). Remember, main() is supposed to return an int, so: return 0; Quote: >} >This works up to a point. For each file it's a different data point,
To say this will work at all is highly optimistic. Quote: >but eventually the program stops reading and fills in the rest of >my csiq array with the integer value -1. Which is suspiciously the >same value that stdio.h has EOF set to.
EOF is an indication of either the end of the file or an error. When you encounter EOF, *stop* reading from the file. Quote: >So, since I know that each file has exactly 32767 characters in them. >And I want to read in the 5th through 32765th values and save them >as integers. How do I get past the apparent EOF that I'm running into.
Save them as integers, or as text representations of integers (which is what you are doing)? Quote: >At least I think it's EOF that I'm hitting. But I checked the 6 or so >files and the integer that the last character read converted to is not >consistant. Nor is the character that follows the last data point read.
Check, check, check! Always check! In this case, check the value returned from getc(). As I said before, *stop* reading when you get EOF. -- ----- Dig the EVEN NEWER, MORE IMPROVED news sig!! ----- -------------- Shaggy was here! --------------- http://aardvark.apana.org.au/~phaywood/ ============= Ain't I'm a dawg!! ============== --
|
Tue, 18 Sep 2001 03:00:00 GMT |
|
|
|