tags:

views:

156

answers:

4

I'm trying to read the last 50 characters in a file by doing this:

FILE* fptIn;
char sLine[51];
if ((fptIn = fopen("input.txt", "rb")) == NULL) {
    printf("Coudln't access input.txt.\n");
    exit(0);
}
if (fseek(fptIn, 50, SEEK_END) != 0) {
    perror("Failed");
    fclose(fptIn);
    exit(0);
}
fgets(sLine, 50, fptIn);
printf("%s", sLine);

This doesn't return anything that makes sense remotely. Why?

+7  A: 

Change 50 to -50. Also note that this will only work with fixed-length character encodings like ASCII. Finding the 50th character from the end is far from trivial with things like UTF-8.

Mehrdad Afshari
+1 for the UTF-8 warning
Hans Kesting
+1  A: 

Try setting the offset to -50.

Moron
A: 

Besides the sign of the offset the following things could make trouble:

A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str.

Use either ferror or feof to check whether an error happened or the End-of-File was reached.

See also

stacker
A: 

fseek(fptIn, 50, SEEK_END)

Sets the stream pointer at the end of the file, and then tries to position the cursor 50 bytes ahead thereof. Remember, for binary streams:

3 For a binary stream, the new position, measured in characters from the beginning of the file, is obtained by adding offset to the position specified by whence..The specified position is the beginning of the file if whence is SEEK_SET, the current value of the file position indicator if SEEK_CUR, or end-of-file if SEEK_END. A binary stream need not meaningfully support fseek calls with a whence value of SEEK_END.

This call should fail. The next call to fgets invokes UB. Try -50 as an offset and also iff the call succeeds try to read it into your buffer

Note: emphasis mine

dirkgently