Traverse FILE line by line using fscanf

后端 未结 4 812
情话喂你
情话喂你 2021-01-03 03:08

Ok so i have a text file database.txt.

Each line is a user with the format below

\"John Smith\"| 4| 80.00| \"123 Lollipop Lane\"| \"New Jersey\"| \         


        
相关标签:
4条回答
  • 2021-01-03 03:44

    I think you need a closing \n in your pattern. I saw the a bunch of scrolling text with the same first line with %[^\n], but with %[^\n]\n I saw the expected output.

    However, if the line in the file exceeds that of the buffer, you may run into a problem where your buffer doesn't have enough space. The results

    Test v1:

    Code

    #include <stdio.h>
    
    
    int main(int argc, char * argv[])
    {
        FILE * database;
        char buffer[30];
    
        database = fopen("test.txt", "r");
    
        if (NULL == database)
        {
             perror("opening database");
             return (-1);
        }
    
        while (EOF != fscanf(database, "%[^\n]\n", buffer))
        {
             printf("> %s\n", buffer);
        }
    
        fclose(database);
        return (0);
    }
    

    Results

    > 12343456567856789
    > zbasdflkjasdfkjklsdafjklas
    > zxcvjkleryjkldhfg
    > 1234567890123456789012341234
    > 12345678901234567890123123asdfjklzxcv;jkl;eqwrtjklkzlcxvjkleqrt41234
    *** stack smashing detected ***: ./fscanf terminated                                                                                                                   
    Segmentation fault (core dumped)
    

    Test v2:

    Let's fix the code so that we don't overrun our buffer. We do this by changing %[^\n]\n to %30[^\n]\n. This tells fscanf that it can only use upto the size of the buffer -- 30.

    Code

    #include <stdio.h>
    
    
    int main(int argc, char * argv[])
    {
        FILE * database;
        char buffer[30];
    
        database = fopen("test.txt", "r");
    
        if (NULL == database)
        {
             perror("opening database");
             return (-1);
        }
    
        while (EOF != fscanf(database, "%30[^\n]\n", buffer))
        {
             printf("> %s\n", buffer);
        }
    
        fclose(database);
        return (0);
    }
    

    Results

    It looks like it worked!

    > 12343456567856789
    > zbasdflkjasdfkjklsdafjklas
    > zxcvjkleryjkldhfg
    > 1234567890123456789012341234
    > 12345678901234567890123123asdf
    > jklzxcv;jkl;eqwrtjklkzlcxvjkle
    > qrt41234
    

    test.txt

    This is what the test file looks like that I was using.

    12343456567856789
    zbasdflkjasdfkjklsdafjklas
    zxcvjkleryjkldhfg
    1234567890123456789012341234
    12345678901234567890123123asdfjklzxcv;jkl;eqwrtjklkzlcxvjkleqrt41234
    

    Any reason you are using fscanf and not fgets?

    One thing to note if you use fgets, you may want to strip the \n character because it will be included as part of the string.

    From cplusplus.com fgets:

    Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.

    Example:

    /* fgets example */
    #include <stdio.h>
    
    int main()
    {
        FILE * database;
        int res;
        char buffer [100];
    
        database = fopen(fileName,"r");
    
        if (NULL == database) {
            perror("opening database file");
            return (-1);
        }
    
        /* while not end-of-file */
        while (!feof(database)) { 
    
            /* we expect buffer pointer back if all is well, get out if we don't get it */
            if (buffer != fgets(buffer, 100, database))
                break;
    
            /* strip /n */
            int len = strlen(buffer);
            if (buffer[len - 1] == '\n')
                buffer[len - 1] = 0;
    
            printf("ATTEMPT TO: Insert user %s\n\n", buffer); 
    
            if (insert_Customer(clients, create_Customer(buffer)) < 0)
                printf("\nERROR: Failed to insert and create customer %s\n", buffer); 
            else
                printf("\nSUCCESS: Inserted Customer %s\n\n", buffer);
        }
    
        /* a little clean-up */
        fclose(database);
    
        return (0);
    }
    
    0 讨论(0)
  • 2021-01-03 03:49

    The problem is that your fscanf will never read the newline at the end of the first line. So when it is called the second time, it will fail (returning 0, not EOF) and read nothing, leaving buffer unchanged.

    You could add a call to fscanf("%*[\n]"); at the end of your while loop to skip the newline (and any blank lines that might occur). Or you could just use fgets instead, which also makes it easier to avoid the potential buffer overflow problem.

    0 讨论(0)
  • 2021-01-03 04:05

    You should put a blank after specifier "%[^\n] " or use "%[^\n]\n". Both will allow you to skip the newline character.

    fscanf(database, "%[\n] ", buffer);
    

    or

    fscanf(database, "%[\n]\n", buffer);
    
    0 讨论(0)
  • 2021-01-03 04:11

    You have to use fgets, instead of fscanf!The fscanf reads until it meats \n (new line) character ,whereas you can use fgets to read all lines with the exact same code you used! Hope that helped :)

    0 讨论(0)
提交回复
热议问题