Troubles with fseek() and reading from file
Asked Answered
D

2

6

I have started learning C (via Youtube and K&R) some time ago and I am trying to write some programs as practice. Currently I want to create a program that reads words from a file and compares the beginning of it with the input from the user. The program successfully compares the first word and gives me a result, but I just can't get the fseek() to move correctly to the next line! (This is the current version of the part that seeks for words.)

fp= fopen("final.txt", "r");
for (i=0; i<8; i++){

    fseek(fp, fileCount, SEEK_CUR);

    fgets(strFile, 20, fp);

    fileCount= strlen(strFile);

    printf("Strlen %d. is: %d\n", i+1, fileCount);
    printf("String is %s", strFile);

    compareStr(strUser, strFile);
};

fclose(fp);

fileCount is set to 0 and strlen() should return the length of the string srtFile, but it doesn't quite well. I even tried setting fseek() manually, but it just wouldn't move. The words from my file are: First, Last, Index, Field, ID, Number, Fire, Film. (each is in a new line). When I run the program and type in F (to search for a word that has a capital f), the output is :

Type in the letters: F
Strlen 1. is: 6
String is First
Match found: First

Strlen 2. is: 6
String is Index
Strlen 3. is: 1
String is
Strlen 4. is: 2
String is D
Strlen 5. is: 5
String is mber
Strlen 6. is: 1
String is
Strlen 7. is: 3
String is ilmStrlen 8. is: 3
String is ilm
Process returned 0 (0x0)   execution time : 2.218 s
Press any key to continue.

I am desperate. Any ideas/clues?

[EDIT] A big thank to everyone who helped me with this!

Dusa answered 27/4, 2015 at 15:10 Comment(8)
Don't you want to increase fileCount? If you're in Windows, you might want to open with "rb" because of the CRLF convention. If you're reading through the file sequentially, why bother with fseek at all?Interfluent
Your filepointer is already at the next word, fgets moves the file pointer as it reads, so the fseek is superfluous.Slotter
BTW fseek may be dangerous for files opened in text mode; explained here. Summary: because of \n <-> \r\n conversion, the parameter to fseek should either be 0 or come from an earlier ftell call. So you should use both fseek and ftell in your program (or none? Maybe you don't need fseek at all?).Clayton
calls to the system functions fopen, fseek, fgets when used in code should have have the returned value checked to assure not error occurs (and/or to enable the code to recognize an error event and have a chance to fix it.Kassab
in the posted code, there is absolutely no need for the call to fseek, as the call will step the file pointer (which after the call to fgets is already moved forward the amount of characters read by fgets)Kassab
for this code to have any hope of working, strFile has to be an array of (at least) 20 characters and fileCount must be initialized to 0. Those details are not revealed in the posted code.Kassab
in reality, lets' assume that 19 characters (fgets) always allows room and appends a NUL string termination char) are read at each call to fgets() Unless each word begins at some multiple of 19 characters into the file, the word will be missed. to avoid missing a word, perhaps use the fseek() to step backward (AFTER a call to fgets()) by 18 bytes so every possible starting position is checked for the wordKassab
however, an even better way would be to read one word at a time then make the comparison. that way, no word would be missed and fseek would not be neededKassab
L
3

The issue here appears because of the fseek SEEK_CUR parameter.

You are moving the cursor twice.

One move is done by fgets (it reads and then moves the cursor forward). And the second move is done manually by fseek.

A solution may be to completely remove the fseek call.

Another solution is to use SEEK_SET instead of SEEK_CUR, but with a counter that holds the total number of character read (including new line character). For this solution to work you also need to change

fileCount= strlen(strFile);

to

fileCount += strlen(strFile) + 1;

SEEK_SET moves the cursor from the beginning of file.

SEEK_CUR moves the cursor from the current position.

Leastways answered 27/4, 2015 at 15:23 Comment(1)
Thanks a lot! I didn't find anywhere that fgets moves the cursor, else I wouldn't have put that fseek(). I put fseek() outside the for-loop and it works!Dusa
D
2

Your problem is that you are not using fseek() correctly.

In your code,

fseek(fp, fileCount, SEEK_CUR);

sets the pointer to where its current at plus the filecount(the offset). That's why it skipped Last and reads Index as string 2.

To fix this, simply remove the fseek() statement.

Dentilingual answered 27/4, 2015 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.