Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

c - fgets() not working after fscanf()

I am using fscanf to read in the date and then fgets to read the note. However after the first iteration, fscanf returns a value of -1.

I used GDB to debug the program step by step. It works fine until the first use of fgets. When I try print out the line read by fgets on the first iteration, it gives me this:

(gdb) print line
$6 = "
test
18/04/2010
test2
03/05/2010
test3
05/08/2009
test4
00000000q352261a370366377267.N=3660000000003000000370xC00000000000000000001000000227000070367377267H36437726736220204doD003542010401000000304oC00p363377277260zC00D363377277
!B006436337727735420104(363377277TzC000000000070367377267010000000000000001000000370xC00010000000000312000000000037726036000010000002770000003643170000344261\0000000000p363377277|23304350362377277 2040405000000|2330430363377277"

It looks like fgets reads the remaining entries and then stores them all in a single string.

I am not sure why it is doing this.

Here is the main code:

int main(int argc, char* argv[]) {
    FILE* file;
    int numEntries, i = 0;
    int index = atoi(argv[1]);
    char line[SIZE];
    JournalEntry *entry;

    /*argument provided is the entry user wants to be displayed*/
    if (argc > 2) {
        perror("Error: Too many arguments provided");
    }
    file = fopen("journalentries.txt", "r");
    if (file == NULL) {
        perror("Error in opening file");
    }

    if (fscanf(file, "%d", &numEntries) != 1) {
        perror("Unable to read number of entries");
    }

    entry = (JournalEntry*)malloc(numEntries  * sizeof(JournalEntry));
    if (entry == NULL) {
        perror("Malloc failed");
    }

    for (i = 0; i < numEntries; i++) {
        if (fscanf(file, "%d/%d/%d", &entry[i].day, &entry[i].month, &entry[i].year) != 3) {
            perror("Unable to read date of entry");
        }

        if (fgets(line, sizeof(line), file) == NULL) {
            perror("Unable to read text of entry");
        }
    }

    printf("%d-%02d-%02d %s: ", entry[index].year, entry[index].month, entry[index].day, entry[index].text);

    if(ferror(file)) {
        perror("Error with file");
    }

    fclose(file);
    free(entry);

    return 0;
}

The file that I have to read: The very first line contains the number of entries to be read

4
12/04/2010
test
18/04/2010
test2
03/05/2010
test3
05/08/2009
test4

The struct JournalEntry located in the header file:

typedef struct {
    int day;
    int month;
    int year;
    char text[250];
} JournalEntry;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Don't mix fscanf() and fgets(), since the former might leave stuff in the stream's buffer.

For a line-oriented format, read only full lines using fgets(), then use e.g. sscanf() to parse what you've read.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...