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
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.
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.
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 .
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.
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.
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.
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.
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.
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.
Just a guess, but I'd assume it's because s1
, s2
, and s3
are arrays.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With