While it looks like the natural solution, I usually advice against using fscanf()
on potentially malformed input.
There are several issues with the function, among them:
- The inability to recover gracefully from an error (short of
ftell()
/ fseek()
), because you don't know where exactly it stopped parsing input.
- The ease with which it leads to using uninitialized values (if the format failed to match the input, and you didn't check the return code properly).
- Some corner cases where
fscanf()
chokes on input where atoi()
/ strtol()
don't ("0xz"...).
All this relegates fscanf()
to read well-formatted input only, i.e. things your own program had written before in a known format.
For any kind of input that might not be in the expected format, I recommend reading a line at a time (fgets()
), and parsing it in-memory, for example with strtol()
:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define LINE_BUFFER_SIZE 256;
// ...
char line[ LINE_BUFFER_SIZE ];
fgets( line, LINE_BUFFER_SIZE, fp );
char * scanptr;
errno = 0;
long number = strtol( line, &scanptr, 0 );
if ( scanptr == line )
{
// not a number...
}
scanptr
now points to where number parsing ended.
number
contains the number parsed, 0 if line did not start with a number, and LONG_MAX
resp. LONG_MIN
if the number found is out of long
range (in which case errno == ERANGE
as well).
I don't know your exact requirements, so I cannot give a good example for what to do if you don't find a number, or what to do with the text. But since you got the line (or, the first LINE_BUFFER_SIZE
characters of a longer line...) in memory, you have the whole range of the string functions at your disposal. strpbrk( line, "0123456789" )
could be used to scan for the next digit, or strpbrk( line, "+-0123456789" )
if you might have +-
in your input...
'1' - '0'
to get the integer value1
. From there it's easy to create integer values no matter the base used for the input. No need to store in a string for later use withatoi
. If you don't want to construct the number on the fly, and useatoi
, this comment gives you a hint about that too. – Cynicismcount += c - '0';
– Right