Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check scanf(..) success without using the number of fields — is there a way?

Tags:

c

scanf

A typical idiom is:

if (scanf("%d%d%d", &a, &b &c) != 3)
    handle_the_failure();

This 3, the number of fields, is redundant. If I change the pattern and the arguments to scanf(..), but forget to change the 3, that's another compile-test-debug cycle, which is a waste of time.

Is there an idiom that allows to check the (absolute) success of scanf(..) without having to write the number of fields in the code? Maybe something like this:

scanf("%d%d%d", &a, &b &c);
if (lastScanfFailedInAnyWay())
    handle_the_failure();

The documentation (see "Return value" section) talks about four different conditions:

  1. End-of-file

  2. Reading error

  3. Matching failure

  4. Encoding error interpreting wide characters

The first two are addressed by feof(..) and ferror(..) (I'm assuming feof(..) implies ferror(..)), and the last — by setting errno to EILSEQ. But I'm interested in a catch-all (i.e. including figuring out if a matching failure occurred).

P.S. Looking at the neat out-of-context example above, this may seem like too much to ask, but consider real practice, where you make many changes rapidly, and there are hundreds of little things like this to keep in mind, that every time you change one thing, you have to change another one elsewhere. Then it becomes clear that developing habits that eliminate dependencies of various sorts pays off.

like image 685
Evgeni Sergeev Avatar asked Jan 28 '26 22:01

Evgeni Sergeev


2 Answers

You could do something like this:

bool wrap_the_scanf(char const *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    int result = vscanf(fmt, ap);
    va_end(ap);
    return result == count_specifiers(fmt);
}

where count_specifiers is a function that reads the string seeing how many % are in it (counting %% as zero).

like image 148
M.M Avatar answered Jan 31 '26 11:01

M.M


You can do something like this:

int nch = -1;
scanf("%d%d%d%n", &a, &b, &c, &nch);
if (nch == -1)
  handle_the_failure();
like image 35
n. 1.8e9-where's-my-share m. Avatar answered Jan 31 '26 10:01

n. 1.8e9-where's-my-share m.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!