David
David

Reputation: 403

Conditionally skipping entire line with just fscanf

Need to skip entire line (comment) if the first character is #

Some solutions in other posts suggested fgets but in my case fscanf is the preferred option as I need to parse each word 1 by 1 later. How can this be done with just fscanf ? Thank you.

File to be read

#This line is a comment <== skip this entire line
BEGIN { 
   THIS IS A WORD
}

CODE

void read_file(FILE *file_pointer, Program *p)
{
    char buffer[FILESIZE];
    int count = 0;
    while (fscanf(file_pointer, "%s", buffer) != EOF)
    {
        if (buffer[0] == '#')
        {
            continue; <============ need to skip until the end of the line
        }
        else
        {
            strcpy(p->wds[count++], buffer);
        }
    }
}

Upvotes: 0

Views: 121

Answers (3)

Andreas Wenzel
Andreas Wenzel

Reputation: 24826

Some solutions in other posts suggested fgets but in my case fscanf is the preferred option as I need to parse each word 1 by 1 later. How can this be done with just fscanf ?

I recommend that you use fgets to read a whole line and then you can use sscanf instead of fscanf to read that line word by word.

#include <stdio.h>

void read_file( FILE *file_pointer )
{
    char line[100];

    while ( fgets( line, sizeof line, file_pointer) != NULL )
    {
        char *p = line;
        char word[50];
        int chars_read;

        //skip line if it starts with "#"
        if ( line[0] == '#' )
        {
            continue;
        }

        //read all words on the line one by one
        while ( sscanf( p, "%49s%n", word, &chars_read ) == 1 )
        {
            //do something with the word
            printf( "Found word: %s\n", word );

            //make p point past the end of the word
            p += chars_read;
        }
    }
}

int main( void )
{
    //this function can also be called with an opened file,
    //however for simplicity, I will simply pass "stdin"
    read_file( stdin );
}

With the input

This is a test.
#This line should be ignored.
This is another test.

this program has the following output:

Found word: This
Found word: is
Found word: a
Found word: test.
Found word: This
Found word: is
Found word: another
Found word: test.

As you can see, the line starting with the # was successfully skipped.

Upvotes: 0

Eric Postpischil
Eric Postpischil

Reputation: 222724

How can this be done with just fscanf?

fscanf(stdin, "%*[^\n]"); will read all characters other than a new-line character, until an error or end-of-file occurs.

* says to suppress assignment of the data being read.

By default, [ starts a list of characters to accept. However, ^ negates that; [^\n] says to accept all characters other than a new-line character.

Upvotes: 2

Barmar
Barmar

Reputation: 780994

Use fgets() after you've read the first word to read the rest of the line.

    while (fscanf(file_pointer, "%s", buffer) != EOF)
    {
        if (buffer[0] == '#')
        {
            fgets(file_pointer, buffer, sizeof buffer);
        }
        else
        {
            strcpy(p->wds[count++], buffer);
        }
    }

Upvotes: 0

Related Questions