I have read somewhere that functions like scanf
and printf
are actually wrappers around functions like fscanf
and fprintf
, with the FILE pointer set to standard input and standard output respectively. Is this guaranteed to be true for all implementations of C, or is that a feature of a specific implementation? I am unable to find any definitive answer to this question, one way or the other.
CodePudding user response:
It's more likely that they're wrappers around vfscanf()
and vfprintf()
, because the 'obvious' implementation is:
int scanf(const char * restrict fmt, ...)
{
va_list args;
va_start(args, fmt);
int rv = vfscanf(stdin, fmt, args);
va_end(args);
return rv;
}
int printf(const char * restrict fmt, ...)
{
va_list args;
va_start(args, fmt);
int rv = vfprintf(stdout, fmt, args);
va_end(args);
return rv;
}
However, it is certainly true at the calling level that these are equivalent:
printf("The data is %d, %d, %d\n", i, j, k);
fprintf(stdout, "The data is %d, %d, %d\n", i, j, k);
and so are these:
int rv = scanf("%d %d %d", &i, &j, &k);
int rv = fscanf(stdin, "%d %d %d", &i, &j, &k);
This could well be why it is claimed that scanf()
is a wrapper around fscanf()
, and printf()
is a wrapper around fprintf()
, but when you actually have to get into the nitty-gritty details of how to implement it, you have to write code similar to what I showed to create portable code. There may be compiler-specific shortcuts that a library implementation could take, but it's relatively unlikely that they'd be used.
I suppose another option is a macro implementation:
#define printf(...) fprintf(stdout, __VA_ARGS__)
#define scanf(...) fscanf(stdin, __VA_ARGS__)
However, the implementation must also provide an actual function printf()
and an actual function scanf()
to meet the requirements of the standard — see §7.1.4 Use of library functions.