Traverse FILE line by line using fscanf

c, file, printf, scanf, traversal

Solution

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);
}

Problem

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"| "08080" ``` When I try do the following: ``` database = fopen(fileName,"r"); while(fscanf(database,"%[^\n]", buffer) != EOF) { 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); } ``` It runs fine for the first line, sending in the ENTIRE line to the create_Customer(char * buffer) function. For some reason I do not understand, after this first line it continually tries to send "John Smith" instead of moving on to the next line. I believe my format is incorrect but I can't figure out how to accomplish what I am trying to accomplish which is read this file line by line and pass each line into the create_Customer function.

Original source

Related problems