Making fscanf Ignore Optional Parameter

12,222

Solution 1

It would appear to me that the simplest solution is to scanf("%d %s", &num, &word) and then fgets() to eat the rest of the line.

Solution 2

The problem is that the %*s is eating the number on the next line when there's no third column, and then the next %d is failing because the next token is not a number. To fix it without using gets() followed by sscanf(), you can use the character class specified:

while(scanf("%d %s%*[^\n]", &num, &word) == 2)
{ 
    assign stuff 
}

The [^\n] says to match as many characters as possible that aren't newlines, and the * suppresses assignment as before. Also note that you can't put a space between the %s and the %*[\n], because otherwise that space in the format string would match the newline, causing the %*[\n] to match the entire subsequent line, which is not what you want.

Solution 3

Use fgets() to read a line at a time and then use sscanf() to look for the two columns you are interested in, more robust and you don't have to do anything special to ignore trailing data.

Share:
12,222
Aditya Mukherji
Author by

Aditya Mukherji

Updated on June 18, 2022

Comments

  • Aditya Mukherji
    Aditya Mukherji almost 2 years

    I am using fscanf to read a file which has lines like
    Number <-whitespace-> string <-whitespace-> optional_3rd_column

    I wish to extract the number and string out of each column, but ignore the 3rd_column if it exists

    Example Data:
    12 foo something
    03 bar
    24 something #randomcomment

    I would want to extract 12,foo; 03,bar; 24, something while ignoring "something" and "#randomcomment"

    I currently have something like

    while(scanf("%d %s %*s",&num,&word)>=2)
    { 
    assign stuff 
    }
    

    However this does not work with lines with no 3rd column. How can I make it ignore everything after the 2nd string?

  • Aditya Mukherji
    Aditya Mukherji over 15 years
    yes.. but i am currently using the number of items scanf matched >=2 to detect the valid portion of the file...... it would be great if i could integrate the process within the scanf itself so as to keep the while loop condition intact
  • user2522201
    user2522201 over 15 years
    I'm not sure I understand, sscanf works pretty much the same was that scanf does, namely it will return the number of items matched so you can use the same logic, i.e. while (fgets(buf, size, stdin) != NULL && sscanf(buf, "%d %s", &num, &word) == 2) { assign stuff }.
  • user2522201
    user2522201 over 15 years
    I hope you are joking about using gets().