Search code examples
cstdioscanf

fscanf - how to process two floats + whitespace + newline?


Using fscanf I want to process text that contains two floats, an arbitrary amount of whitespace before, between, or after the floats (including newlines/returns), and a newline character at the very end. If there are more/fewer than two numbers, then I want to detect that and report an error.

This seems to work for handling the whitespace, but it won't detect if there's more than two floats present:

fscanf(f, "%f %f", &sx, &sy);

And this seems to work just as well:

fscanf(f, "%f %f%*[ \n\t\r\f\v]\n", &sx, &sy);

Is there a better way to handle this?


Solution

  • I don't know how to do it with a single *scanf, I don't think it's possible due to the last part of your request, *scanf can't read an arbitrary length character sequence matching a simple regex and ending with a specified character.

    int character;
    bool trailingNewLine;
    
    if (fscanf(f, "%f%f", &sx, &sy) < 2)
        // not matching "whitespace-float-whitespace-float"
        // being more accurate could be painful...
    
    // read arbitrary quantity of white space ending with '\n'
    while (isspace(character = getc(f)))
        trailingNewLine = (character == '\n');
    
    // the last one wasn't white space, doesn't belong to this one
    ungetc(character, f);
    
    if (!trailingNewLine)
        // missing newline at the end
    
    // OK!