fgetc() function reads characters from a text file in Ubuntu.
the last character before EoF is with code = -1.
what the heck is that?
in text editor file seems ok, no strange symbols at end.
while (!feof(fp))
{
c = fgetc(fp);
printf("%c %i\n", c, c);//
}
feof is meant to signal that you've tried to read past the end of file - which means that you first have to reach it. So it will only work after you try to read and the system realizes you're at the end. And what does fgetc return if you try to read past the end of file? EOF (conveniently, -1 - which is why fgetc returns an int instead of a char).
So what's happening is that you enter the loop - because you haven't yet tried to read past at the end yet - and call fgetc which returns -1 because you tried to read past the end of the file. The next time around the loop, feof tells you that you've already hit the end of the file and tried to read past it and you break out.
You should read the documentation of functions you intend to use: feof and fgetc documentation explain this. But even if they did not, a simple google search would have answered your question: Why is “while ( !feof (file) )” always wrong?.
Related
I just read in a string using the following statement:
fgets(string, 100, file);
This string that was just read in was the last line. If I call feof() now will it return TRUE? Is it the same as calling feof() right at the start before reading in any lines?
No, don't use feof() to detect the end of the file. Instead check for a read failure, for example fgets() will return NULL if it attempts to read past the end of the file whereas feof() will return 0 until some function attempts to read past the end of the file, only after that it returns non-zero.
Does feof() work when called after reading in last line?
No.
feof() becomes true when reading past the end of data. Reading the last line may not be pass the end of data if the last line ended in '\n'.
The short answer is NO. Here is why:
If fgets successfully read the '\n' at the end of the line, the end-of-file indicator in the FILE structure has not been set. Hence feof() will return 0, just like it should before reading anything, even on an empty file.
feof() can only be used to distinguish between end-of-file and read-error conditions after an input operation failed. Similarly, ferr() can be used to check for read-error after an input operation failed.
Programmers usually ignore the difference between end-of-file and read-error. Hence they only rely on checking if the input operation succeeded or failed. Thus they never use feof(), and so should you.
The behavior is somewhat similar as that of errno: errno is set by some library functions in case of error or failure. It is not reset to 0 upon success. Checking errno after a function call is only meaningful if the operation failed and if errno was cleared to 0 before the function call.
If you want to check if you indeed reached to the of file, you need to try and read extra input. For example you can use this function:
int is_at_end_of_file(FILE *f) {
int c = getc(file);
if (c == EOF) {
return 1;
} else {
ungetc(c, file);
return 0;
}
}
But reading extra input might not be worthwhile if reading from the console: it will require for the user to type extra input that will be kept in the input stream. If reading from a pipe or a device, the side effect might be even more problematic. Alas, there is no portable way to test if a FILE stream is associated with an actual file.
I'm relatively new to C, my question is:
Is it ALWAYS true that there are only EOF chars past the end of a file?
Example code:
FILE *fr;
int i;
fr=fopen("file.txt","r");
for (i=0;i<20;i++) {
putchar(getc(fr));
}
fclose(fr);
Output:
user#host:~$ ./a.out | xxd
0000000: 6173 640a ffff ffff ffff asd.......
(file.txt contains asd\n)
Answer: there aren't any characters beyond the end of a file. My MSVC manual page here says that if you read past the end of the file, getc() returns EOF.
It does not matter how many times you try to make getc() read past the end of the file, it won't. It just keeps returning EOF.
The EOF is not part of the file marking its end - it is a flag value returned by getc() to tell you there is no more data.
EDIT included a sample to show the behaviour of feof(). Note, I made separate printf() statements, rather than merging them into a single statement, because it is important to be clear what order the functions feof() and getc() are called.
Note that feof() does not return a non-0 value until after getc() returned EOF.
#include <stdio.h>
int main( void )
{
FILE *fr;
int i;
fr=fopen("file.txt","r");
for (i=0;i<6;i++) {
printf("feof=%04X, ", feof(fr));
printf("getc=%04X\n", getc(fr));
}
fclose(fr);
}
Program input file:
abc\n
Program output:
feof=0000, getc=0061
feof=0000, getc=0062
feof=0000, getc=0063
feof=0000, getc=000A
feof=0000, getc=FFFFFFFF
feof=0010, getc=FFFFFFFF
So, you can't use feof() to tell you the end of file was reached. It tells that you made a read error after reaching the end of file.
There are no EOF characters in a file, nor any characters after the end of a file (it's the end of the file, after all). Rather, EOF is a special value used by getc (and others) to indicate that there isn't anything to read. You can use feof and ferror to see whether that EOF was caused by reaching the end of the file, or if an error ocurred.
What you are seeing are the EOF values (cast to an unsigned char) that getc returned after reaching the end of the file.
Normally, there aren't "EOF chars" in the file to mark the end. EOF is just an integer value, that does not correspond to a valid char value, that is returned by some functions when there's nothing left in the file.
In your example, you see the ff values after the contents of the file because when getc() returns EOF, indicating there's nothing left to read, you're displaying it as a char... effectively displaying the char corresponding to the low bits of the EOF value and ignoring the high bits. If you read the file in a different way, you might not see that result.
I am aware that in c there are functions getc() and ungetc().
I would need this counter-function for fgetc(), sadly unfgetc() doesn't really exist. So I tried writting it on my own.
This is how it looks:
int getNextChar(FILE* fd)
{
// get the character
int nextCharacter = fgetc(fd);
// fseek it back, so you don't really move the file descriptor
fseek(fd, -1, SEEK_CUR);
// returning the char (as int)
return nextCharacter;
}
But well... that doesn't seem to work.
I call it inside a while loop, like this.
while ( (c = fgetc(fd)) != EOF)
{
cx = getNextChar(fd);
printf("%c", c);
}
It gets stucked on the last character of the file (it prints it with every iteration to infinity). Now a little explanation why I need that in case that I'm doing it all wrong and that there would be another suitable solution.
I need to check the next character on being EOF. If it is EOF, I force send token, that is created in the while loop (this part is not important for my issue, so I didnt include it).
I am going through the loop and whenever I find a character that doesnt respond to a mask, I assume that I should send a token and start making a new one with that character that doesnt respond. Naturally, when I read the last char in the file, no next iteration will be done, therefore I won't send the last token. I need to check next char to be EOF. If it is EOF, I force send token.
Thank you for your advices!
You need to check that nextCharacter isn't EOF, since if it is, you'll still back off, thus causing the outer reading to never see the end of the file. Also check return values of more functions, like fseek().
I was given an assignment in C language about reading and writing in a file.
I have read different codes on different websites and also their explanations. but there is one question that remained unanswered! Following is the general code I found on different sites:
#include <stdio.h>
void main()
{
FILE *fp;
int c;
fp = fopen("E:\\maham work\\CAA\\TENLINES.TXT","r");
c = getc(fp) ;
while (c!= EOF)
{
putchar(c);
c = getc(fp);
}
fclose(fp);
}
My questions are simple and stright.
in line c = getc(fp) ; what is that C receives?? address? character? ASCII Code?? what?
and
while (c!= EOF)
{
putchar(c);
c = getc(fp);
}
here how is c able to read the file character by character?? there is no increment operator... does the pointer "fp" helps in reading the code??
lastly, why is putchar(c); used in printing ? why not use printf("%C", c); ?
getc() returns the integer value of the byte at the current position in the file handle, then advances that position by one byte.
putchar() is simpler than printf.
1 minute googling got me this.
C++ reference
tutorial points
wikipedia
Quoting reference documentation (C++ here, but probably very similar in C).
int getc ( FILE * stream );
Get character from stream Returns the character currently pointed by the internal file position indicator of the specified stream. The internal file position indicator is then advanced to the next character.
If the stream is at the end-of-file when called, the function returns EOF and sets the end-of-file indicator for the stream (feof).
If a read error occurs, the function returns EOF and sets the error indicator for the stream (ferror).
getc and fgetc are equivalent, except that getc may be implemented as a macro in some libraries. See getchar for a similar function that reads directly from stdin.
Further reading gives us:
On success, the character read is returned (promoted to an int value).
The return type is int to accommodate for the special value EOF, which indicates failure: If the position indicator was at the end-of-file, the function returns EOF and sets the eof indicator (feof) of stream.
If some other reading error happens, the function also returns EOF, but sets its error indicator (ferror) instead.
Here we read
This function returns the character read as an unsigned char cast to an int or EOF on end of file or error.
And on wikipedia
Reads a byte/wchar_t from a file stream
I would like to read a file called "input" with a lot of lines and 10 columns into an array using C. I wrote the following code:
FILE *file;
file=fopen("input","r");
i=0;
while ( fgetc(file) != EOF )
{
fscanf(file,"%e\t%e",&x[i],&y[i]);
i++;
}
The problem that I am ecoutering is that the first element of the file is not read. It is read however when the file contains an initial indent.
Could you help me?
Thank you in advance.
fgetc() reads a character and returns it and increments the file pointer. next when you call fscanf(), the first character won't be seen as its already past first character. If you want, only use fscanf() and check for EOF to detect end of file.