scanf internals

Discussion in 'C Programming' started by Bill Cunningham, May 24, 2014.

  1. 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
     
    Bill Cunningham, May 24, 2014
    #1
    1. Advertisements

  2. 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.
     
    Malcolm McLean, May 24, 2014
    #2
    1. Advertisements

  3. 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.
    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.
    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.
    There is no buffer so what overflow are you contemplating?
    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.
     
    Barry Schwarz, May 24, 2014
    #3
  4. Research what? Is the internals of scanf posted somewhere? I've never
    seen it.
    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
    I thought & passed an address of something.
    No shit.

    There is no
    No shit.

    Why do you think the internals
    Never said there was one. (A relastionship). Read the post.
     
    Bill Cunningham, May 24, 2014
    #4
  5. Bill Cunningham

    Osmium Guest

    Your best bet is the Plauger book. I really strained to come up with that
    "p f" part - it's been a while
    Keep in mind that there is not /a/ scanf, each scanf is one programmers'
    coding for one machine at one time.

    http://www.amazon.com/The-Standard-Library-P-J-Plauger/dp/0131315099

    I feel sure you will order this in the next 15 minutes. :(
     
    Osmium, May 24, 2014
    #5
  6. Bill Cunningham

    Osmium Guest

    And then I typed p f instead of p j. Jeez. Maybe pf was an earlier guess.
     
    Osmium, May 24, 2014
    #6
  7. 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.
    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.
    This is irrelevant to your question about scanf, so I'll ignore it.
     
    Keith Thompson, May 24, 2014
    #7
  8. Bill Cunningham, May 24, 2014
    #8
  9. [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
     
    Bill Cunningham, May 24, 2014
    #9
  10. 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!!
     
    Bill Cunningham, May 25, 2014
    #10
  11. Bill Cunningham

    luser droog Guest

    And the crowd goes wild!!
    Nicely done.
     
    luser droog, May 25, 2014
    #11
  12. [snip]
    No. It was put there mistakenly by habit. I'm so used to using it with
    printf.
    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
     
    Bill Cunningham, May 25, 2014
    #12
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.