As we know, it's a good idea to check scanf
for errors like this:
if(scanf("%d %d %d", &x, &y, &z) != 3) {
/* Handle error */
}
But I wonder if there is any way to automatically detect that it should be 3.
One approach I have thought about is to declare the format string separately and then parse it. Something like this:
const char format[] = "%d %d %d";
size_t n = count(format);
if(scanf(format, &x, &y, &z) != n) {
But I have no idea how to implement count
properly. I could do something like counting number of %
but that would be very error prone. If there's no library function for this, I suspect it would be incredibly hard to get it right.
Another approach I have considered is doing something like this:
void wrapper(const char *format, ...) {
va_list arg;
va_start(arg, format);
size_t n = count(arg);
int done = __vfscanf_internal (stdin, format, arg, 0);
if(done != n) {
But as far as I can see, there's no way to write the function count
here. The specs of va_arg
says: "If va_arg is called when there are no more arguments in ap, the behavior is undefined." so I cannot loop it until NULL or something like that.
A third approach is to see if scanf supports writing this number to a variable like this:
int n = scanf("%<somespecifier>%d %d %d", %c, %x, %y, %z);
if(n != c) {
/* Handle error */
}
But that does not seem to be an option.
So I am at a loss here. Is there any way to do what I want?
My ultimate goal with this is to write a "safe" (I know that's a relative term when it comes to this) version of scanf that exits on failure. Something like
void safe_scanf(const char *format, ...) {
/* Code */
if(<wrong number of assignments>) {
perror("Wrong number of assignments");
exit(EXIT_FAILURE);