locked
Is anyone else having trouble with scanf? RRS feed

  • Question

  • Hi everyone,

    I just downloaded Microsoft Visual Studio 2010 yesterday. I tried running this simple program just to test it out and I am having trouble with scanf.

    Here is my program:

    #include <stdio.h>
    #include <math.h>
    #include <conio.h>
    //double calculateCharges(double x); //function for calculating the charges
    int main(void){
    	int value = 0;
    	printf("Enter a value and I will give it back to you:");
    	scanf("%d",value);
    	printf("Your value is %d",value);
    	getch();
    }

    So my problem is that when the terminal windows pop up, I get the printf statement but once I type something in I get this error. How do I fix it?

    This is the error:

    Unhandled exception at 0x5ee1e42e (msvcr100d.dll) in 5.9ParkingCharges.exe: 0xC0000005: Access violation writing location 0x00000000.

    Tuesday, March 27, 2012 9:19 PM

Answers

  •    int value = 0;
       printf("Enter a value and I will give it back to you:");
       scanf("%d",value);

    The last line should be:

        scanf("%d", &value);

    Dave

    • Proposed as answer by Ante Meridian Tuesday, March 27, 2012 10:23 PM
    • Marked as answer by MexterO Tuesday, March 27, 2012 10:50 PM
    Tuesday, March 27, 2012 9:33 PM

All replies

  •    int value = 0;
       printf("Enter a value and I will give it back to you:");
       scanf("%d",value);

    The last line should be:

        scanf("%d", &value);

    Dave

    • Proposed as answer by Ante Meridian Tuesday, March 27, 2012 10:23 PM
    • Marked as answer by MexterO Tuesday, March 27, 2012 10:50 PM
    Tuesday, March 27, 2012 9:33 PM
  • Why do we do that again Dave? Why do we have to tell the compiler we want to store the address value, why is the name not sufficient enough?
    Tuesday, March 27, 2012 10:52 PM
  • >Why do we have to tell the compiler we want to store
    >the address value,

    You're NOT telling it to *store* the address.
    You're telling it the address where scanf is
    to store the *value* it gets from the stream.

    comp.lang.c FAQ list  Question 12.12
    Q: Why doesn't the call scanf("%d", i) work?
    http://c-faq.com/stdio/scanf1.html

    - Wayne
    Tuesday, March 27, 2012 10:58 PM
  • The code generated by the C/C++ compiler doesn't know about variable
    names. It only knows about variable address and values.
     
    Tuesday, March 27, 2012 10:59 PM
  • Okay, let me get this straight value has an associated address with it in memory so scanf needs that address to store the value it gets? So value lets say has address 0x00CF. Its asking for that?

    Tuesday, March 27, 2012 11:09 PM
  • When you pass a variable name to a function, you are telling it to use the contents of the variable. So

    int i = 0;
    scanf("%d", i);

    would end up trying to store the result in a null pointer.

    The thing to remember with passing variables as a parameter is that you are not passing the variables themselves, you are passing the contents. It will lose all information about where the value is stored as soon as you call the function and all scanf knows is that you gave it a value 0 and that is where it will try to store the result.

    When you deal with variables you should think of them as containers and whenever you refer to a particular variable you are actually refering to the contents of the container. (This doesn't work well with assignment as it copies the contents, not moves it though.) If you want to refer to the container itself then you have to use the & operator to say "I want the container, not the contents" and then writing &variable will allow it to store it in variable itself.

    As a simple rule though, when dealing with C functions, if you want to allow a function you are calling to modifying the variable you are passing, you must take the address and pass that instead. Yes, scanf is a C function.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.


    • Edited by Darran Rowe Tuesday, March 27, 2012 11:29 PM
    Tuesday, March 27, 2012 11:28 PM
  • Thanks, you explain way better than my teacher. I just wish he could have explained it that way.
    Tuesday, March 27, 2012 11:31 PM
  • Hold on why is it then for printf you don't have to?

    What would be the difference between

    printf("Here is the value %d",value);

    and

    printf("Here is the value %d",&value);

    Tuesday, March 27, 2012 11:34 PM
  • Well, printf expects the value directly, in other words, printf works with the contents of the container, so with

    printf("%d", value);

    you are passing the contents of value to printf and the %d will see what was passed and then prints it out. If you did

    printf("%d", &value);

    then you would be refering to the "container" of value directly so what would get printed is the memory address of value.

    So for basic types remember that & is needed for variables in scanf but not needed for variables in printf. (It gets awkward with %s, so lets ignore that for now).


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.


    • Edited by Darran Rowe Wednesday, March 28, 2012 6:17 AM As pointed out, I missed a &
    Wednesday, March 28, 2012 12:01 AM
  • You probably meant

         printf("%p\n", &value);

    Wednesday, March 28, 2012 1:11 AM
  • Yes, I missed the addressof operator on the second printf. Thanks for pointing it out.

    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

    Wednesday, March 28, 2012 6:18 AM
  • All arguments are inputs to the function and are passed by VALUE.

    In the case of
         printf("Here is the value %d",variable);
    the argument variable evaluates to the current contents of variable (its value, for example, 42) with type int.  This is exactly what you want printf to print.

    In the case of
         printf("Here is the value %d",&variable);
    the argument &variable evalutes to the location of variable (its address, for example 0x12345678) with type pointer to int.  There is hardly ever any reason to print the address of a variable unless you are writing a debugger.  Furthermore, the %d tells printf that the argument has type int which in this case is a lie.  This type of call to printf invokes undefined behavior.  To be correct, it would need to be
         printf("Here is the value %p",(void)&variable);
    The %p tells printf the argument is a pointer to void.  The expression &variable evaluates as described above and the cast operator converts it from pointer to int (int*) to pointer to void (void*).

    Getting back to scanf, its purpose is to extract values from the input stream and give them to you.  Since it is capable of providing multiple values, the normal return statement (which is limited to a single value) used by functions such as sqrt is inadequate.  The solution for C and C++ is to give scanf the addresses where you want those values stored.

    In your original statement
        scanf("%d",value);
    the argument value evaluates to the current contents of value which is 0 with type int.  Furthermore, the %d tells scanf that the argument should have type pointer to int.  Since the presumed and actual types don't match, this is another example of undefined behavior.  Even if the behavior were defined, telling scanf to store a value in location 0 is a no-no.  It is not a location your program can access.  And finally, since scanf is about to replace the contents of value, it really doesn't need the current contents at all.

    In the corrected statement
        scanf("%d",&value);
    the argument evaluates to the address of value (its location) with type pointer to int.  Now scanf knows where to store the int it extracts from the input stream.

    Wednesday, March 28, 2012 6:29 PM