简体   繁体   中英

format specifiers in scanf( ) in C?

Why do we pass the format specifiers to scanf( ) in C as its parameters?

I mean, can't we just do

scanf( &var ); // Here, var is any pre-declared variable.

the type of var can be fetched from its declaration. Why is this not allowed ?

I see the below code as a waste of memory.

scanf( "%d" , &var );

The type cannot be "fetched from it's declaration". There is nothing magical about scanf() , it's just a function. A function in C cannot access meta information about variables.

This is why, in general, function arguments are declared including their type. For variable-argument functions such as scanf() , the first argument is not optional and it is used to describe the number and type of the other arguments in some fashion chosen by the function itself.

You clearly need to read some book on C programming to get better understanding of the core concepts. Unlike some other languages, C doesn't have I/O mechanism baked into the language. scanf() is just a library function and as such, this function has no way to automagically know the type of the variable it is supposed to fill.

Because %d will simply specify what the type of var is, there is no memory wastage. scanf(&var) would not work because the function is not designed to accept arguments that way.

You know that variables in C can be of different types:

  • int: Integer
  • char: Character
  • float: Floating point number.
  • ...

Unlike other languages, variable types cannot be implicitly inferred at compilation time in C. That is why you always declare the type of your variables ( Example: int a or char c).

Because scanf is just a function in C, and because functions in C should take parameters of a specific type, people who coded C decided to use the following format:

     scanf("%d", &var) ; // for integers
     scanf("%c", &var); //for chars
     scanf("%f", &var); //for double and floats.

using %d or %c does not waste memory or whatsoever. you can think about it as a flag that specifies the type of the input variable.

Could the developers of C do it without %d, %c...etc? Yes they could, but then, they have to handle all possible exceptions that might arise from sending the wrong type.

Suppose the developers of C used just the following format

    scanf(&var);

That is surly very concise, but then you will have to use the same syntax to send chars/int/double...etc, and then the function scanf has to figure out a way to decide about the type of the variable that was sent. Remember what I told you before? variable types CANNOT be implicitly inferred at compilation time, and thus, this task will be almost impossible.

They could however use a different scanf function for every type. For example:

    scanfInt(&var);     //for integers.
    scanfFloat(&var);   //for floats.
    ...
    ...

That would work perfectly, but it makes less sense to replicate the same code of scanf and use different functions just because the type is different.

So what is the solution? ==> Use the same function name ( scanf ), and then add a parameter (%d, %f, %c..) that will be used internally as a flag by C to know the parameter type.

I hope now you have a better understanding of the use of %d, %f....

There are two major points you are missing here.

First, we humans sitting at the keyboard will write something like:

char var = '0';

And we know that the "type" of this variable is char and we probably intend to store a character there. Once the compiler gets a hold of this it removes these "human" elements all that is left is at some memory location there is 1 byte reserved, further references to places in the code where we wrote "var" will interact with this memory location. That is all the compiler knows, there is no understanding of the intended variable "type".

Second, the format specificers do so much more than just indicate a simple type. Look at any page explaining scanf() and you'll see a long list, take special note of things like scan sets, negated scan sets, and expected input lengths.

Let's say I want the user to enter just a single digit, 0-9, well I don't have to just assume they will do as I ask, I can help ensure they will by using the format specifiers in scanf():

int var = 0;
print("enter 1 digit (0-9):\n");
scanf("%1d", &var);

Now, no matter how many digits they enter, I'll only have stored the first one.

What if you have a string that you want to read from the user, and you want to read everything up until you hit a new line character (read over spaces). We'll there are a number of options for this, but scanf can do it too. The "standard" to read a string is:

scanf("%s",some_string);

But that will stop at any whitespace character, so you wouldn't want scanf() to make an assumption in this case, you'd want to be able to use a specific negated scanset:

scanf("%[^\n]",some_string);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM