scanf internals


B

Bill Cunningham

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.

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...

char p[50];
fgets(p,sizeof p,stdin);

And a char * is returned.

Bill
 
Ad

Advertisements

M

Malcolm McLean

Does anyone know anything about the internals of scanf.
The best way to understand it is to have a got at writing one.

Try to write mysscanf()

int mysscanf(char *str, char *fmt, ...)

To start with, just support the %d format specifier. Then add the other ones.
 
B

Barry Schwarz

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

How many times have people requested you stop guessing and perform
research. There is no generic pointer in this code. The only pointer
is a pointer to int.
pointer is declared *outside* this function but a pointer/pointee address is

What on earth is a pointer/pointee address? There is no pointer
address in this code. There is a pointer value. As noted above, that
pointer value is the address of an int.
most obviously desired. But a value is declared in this instance and its
address passed.

There is no value declared. There is an expression which evaluates to
a value and the value, NOT ITS ADDRESS, is passed.
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

Since the variable a has not been given a value, its value is
indeterminate. If the address passed to scanf were dereferenced, that
would lead to undefined behavior by attempting to evaluate an
indeterminate value. So no, there is no dereferencing of the value
passed as the second argument.
quite possibly without warrant been afraid of buffer overflow here. Is that

There is no buffer so what overflow are you contemplating?
not a possibility. I am going on old advice for my input and I use this...

char p[50];
fgets(p,sizeof p,stdin);

And a char * is returned.

You really do love adding a completely irrelevant topic at the end of
your posts. fgets is completely different than scanf. There is no
ellipsis in the declaration of fgets. Why do you think the internals
of scanf (your subject) have any relationship to using fgets.
 
B

Bill Cunningham

Barry Schwarz said:
How many times have people requested you stop guessing and perform
research. There is no generic pointer in this code. The only pointer
is a pointer to int.

Research what? Is the internals of scanf posted somewhere? I've never
seen it.
What on earth is a pointer/pointee address? There is no pointer
address in this code.

So there's no "void *" anywhere in scanf's parameters? Or anything else
wanting an adress? Why do we use the ampersand then?


There is a pointer value. As noted above, that
pointer value is the address of an int.


There is no value declared. There is an expression which evaluates to
a value and the value, NOT ITS ADDRESS, is passed.


Since the variable a has not been given a value, its value is
indeterminate. If the address passed to scanf were dereferenced, that
would lead to undefined behavior by attempting to evaluate an
indeterminate value. So no, there is no dereferencing of the value
passed as the second argument.

I thought & passed an address of something.
quite possibly without warrant been afraid of buffer overflow here. Is
that

There is no buffer so what overflow are you contemplating?
not a possibility. I am going on old advice for my input and I use this...

char p[50];
fgets(p,sizeof p,stdin);

And a char * is returned.

You really do love adding a completely irrelevant topic at the end of
your posts. fgets is completely different than scanf.

No shit.

There is no
ellipsis in the declaration of fgets.

No shit.

Why do you think the internals
of scanf (your subject) have any relationship to using fgets.

Never said there was one. (A relastionship). Read the post.
 
O

Osmium

Osmium said:
Your best bet is the Plauger book. I really strained to come up with that
"p f" part - it's been a while

And then I typed p f instead of p j. Jeez. Maybe pf was an earlier guess.
 
Ad

Advertisements

K

Keith Thompson

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.
 
B

Bill Cunningham

[snip]

I haven't even touched the variable arguments list. I know ellipses is
involved. I have studied 1/3 of the ANSI standrd probablly because it takes
programming skill to use functions and come up with things. I only study
"code" so I do a little coding. I only hope one day I'll gain enough
programming skills to put things together. You're post has been saved on my
disk and I will study it.

Bill
 
B

Bill Cunningham

Osmium said:
:

And then I typed p f instead of p j. Jeez. Maybe pf was an earlier guess.

I have no idea what you're talking about so I will assume you're trying
to be funny. So ha ha I guess. I just keep guessing!!
 
L

luser droog

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.

And the crowd goes wild!!
Nicely done.
 
Ad

Advertisements

B

Bill Cunningham

[snip]
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.

No. It was put there mistakenly by habit. I'm so used to using it with
printf.
This is documented in the standard and in any documentation you
have for the scanf() function.

I understand. I'm just not sure about variable argument lists right now. I
don't want to get in to much. There's so much to learn now.

Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

pass by address 42
scanf and ampersand 4
dereferencing problem 46
Custom Scanf Routine 29
pointers 25
Need help - pointers 6
unaligned pointer access 28
error free function and how to debug 3

Top