Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scanf() (C Language ) confused me

Tags:

c

scanf

When do I need to insert/don't insert & for scanf() in C? Thank you.

int main()
{
    char s1[81], s2[81], s3[81];

    scanf("%s%s%s", s1, s2, s3);

    // If replace scanf() with the expression below, it works too.
    // scanf("%s%s%s", &s1, &s2, &s3);

    printf("\ns1 = %s\ns2 = %s\ns3 = %s", s1, s2, s3);

    return 0;
}

//programming is fun
//
//s1 = programming
//s2 = is
//s3 = fun
like image 575
Nano HE Avatar asked Jun 17 '10 01:06

Nano HE


People also ask

What does scanf () do in C?

In C programming, scanf() is one of the commonly used function to take input from the user. The scanf() function reads formatted input from the standard input such as keyboards.

What is wrong with scanf in C?

Explanation: The problem with the above code is scanf() reads an integer and leaves a newline character in the buffer. So fgets() only reads newline and the string “test” is ignored by the program. 2) The similar problem occurs when scanf() is used in a loop.

What can I use instead of scanf in C?

The most common ways of reading input are: using fgets with a fixed size, which is what is usually suggested, and. using fgetc , which may be useful if you're only reading a single char .

Why should I not use scanf?

The real problem with scanf has a completely different nature, even though it is also about overflow. When scanf function is used for converting decimal representations of numbers into values of arithmetic types, it provides no protection from arithmetic overflow. If overflow happens, scanf produces undefined behavior.


8 Answers

scanf puts the scanned values in the address pointed by it's arguments. The & is the address operator, and it's used to take the address of a variable.

But, you are using arrays, and arrays are downgrade to pointers when used as functions arguments. So, you don't need to use the & operator in the case of arrays.

Example:

char s[81];
int n;
int* nptr;
//Initialize nptr to some meaningful value
scanf("%s %d %d",s,&n,nptr);

In this case, we need to use the & operator to get the address were n is kept. We don't need to use it with nptr, because it is already a pointer to someplace in the memory, neither with s, because an array gets downgrade to a pointer when it's passed to a function.

like image 111
cake Avatar answered Oct 12 '22 05:10

cake


The arguments after the format specifier must be pointers. When an array name is passed to a function, the location of the initial element is passed, so you don't need to use the & at all in your example. You could do this though (from K&R):

int day, year;
char monthname[20];

scanf("%d %s %d", &day, monthname, &year);

Since day and year are int, you must use the & to get the address of those variables. Since monthname is an array, no & is required.

like image 24
Bill the Lizard Avatar answered Oct 12 '22 06:10

Bill the Lizard


In C, when you are dealing with arrays:

int c_array[24];
c_array == &c_array == &c_array[0]

Yeah, its funny - they look the same (the difference is in the types). Read this.

like image 24
Sudhanshu Avatar answered Oct 12 '22 04:10

Sudhanshu


From the comp.lang.c FAQ: I thought you always needed an & on each variable passed to scanf.

I highly recommend reading the rest of the comp.lang.c FAQ.

like image 34
jamesdlin Avatar answered Oct 12 '22 05:10

jamesdlin


s1 returns the address of the first element of the array, while &s1 returns the address of the array itself. The address of the first element and the address of the array itself are identical, hence why both representations work.

like image 33
Blair Holloway Avatar answered Oct 12 '22 04:10

Blair Holloway


Just a guess, but I'd assume it's because s1, s2, and s3 are arrays.

like image 43
icktoofay Avatar answered Oct 12 '22 04:10

icktoofay


If a is an array, both a and &a result in a pointer in this context:

  • a does due to the array decaying to a pointer (C99, §6.3.2.1/3):

    Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.

    ... emphasis added

  • &a does as a result of the & operator - it returns a pointer to the object.

like image 33
Georg Fritzsche Avatar answered Oct 12 '22 04:10

Georg Fritzsche


Scanf accepts variable number of parameters. first argument of scanf is format and after that n addresses where values to be stored while n is the number of format specified in format string. since you are using array, to store values you have to provide base address of the array.


//If int
int i;
scanf("%d",&i); // store int value at address &i

float f;
scanf("%f",&f); //store float value at address &f

int a[10];
scanf("%s",a); //store string or array value at a

if using a in last line confuses you, you can try the same thing with address of first element which is &a[0].

Hope it helps,
GG

like image 39
GG. Avatar answered Oct 12 '22 06:10

GG.