Bill Cunningham said:
Does anyone know anything about the internals of scanf. I see the first
parameter but the next is an ellipses. Like a variable argument type setup.
int a;
scanf("%d\n",&a);
Now I am guessing because I don't know of any way to know for sure that
there is a generic pointer in there. Because an address is passed. No
pointer is declared *outside* this function but a pointer/pointee address is
most obviously desired. But a value is declared in this instance and its
address passed.
Multiple misconceptions.
There is no "generic pointer" here. An argument to a variadic
function can be of just about any type, pointer or otherwise.
It happens that most of the arguments to scanf() need to be of
pointer type.
No pointer *object* is declared because no pointer object needs to
be declared. The argument passed to scanf is a pointer *value*.
Similarly, for a function that needs an int argument, you can
pass a literal 42 to the function without defining an int object.
&a is an expression of pointer type.
Inside of the scanf function, is the value stored at the pointee address
dereferenced? That is all that would make sense to me. I have always and
quite possibly without warrant been afraid of buffer overflow here. Is that
not a possibility. I am going on old advice for my input and I use this...
There are multiple open source implementations of the C standard
library, including scanf. I'm not sure that reading them is going
to be particularly helpful.
Here's an incomplete implementation of scanf() that I just threw
together, incorporated into a small test program. There are three
things it needs to do: parse the format string, read the arguments,
and perform the actual input. This version shows, in simplified
form, how the arguments are read; the other tasks are delegated to
the real scanf() function.
========================================
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int my_scanf(const char *format, ...) {
if (strcmp(format, "%d") != 0) {
fprintf(stderr, "Unsupported format\n");
exit(EXIT_FAILURE);
}
va_list ap;
va_start(ap, format);
int *arg = va_arg(ap, int*);
int scanf_result = scanf(format, arg);
va_end(ap);
return scanf_result;
}
int main(void) {
int n;
int my_scanf_result = my_scanf("%d", &n);
printf("my_scanf() returned %d, n = %d\n", my_scanf_result, n);
}
========================================
Variadic functions use macros defined in <stdarg.h> to access
the arguments. (The way those macros are defined will vary from
one implementation to another, and needn't concern us here.)
Such a function needs to know the expected type of each argument
before it can retrieve it. In this painfully simplified example,
my_scanf() assumes that the format string is exactly "%d" and that
the single argument following the format string is of type int*.
An actual implementation of scanf() needs to parse the format string
and decide how to invoke the va_arg() macro for each argument.
I've also changed the format string you used in your example, "%d\n",
to "%d". The "\n" doesn't tell scanf to read a '\n' character;
rather, it tells it to read arbitrarly many characters until it
either sees a non-whitespace character or until it runs out of
characters to read. That's almost certainly not what you want.
This is documented in the standard and in any documentation you
have for the scanf() function.
char p[50];
fgets(p,sizeof p,stdin);
And a char * is returned.
This is irrelevant to your question about scanf, so I'll ignore it.