简体   繁体   中英

Input in C using format specifiers in scanf()

I could successfully execute the block of code below, however, could not understand the output of the code logically.

#include<stdio.h>
int main()
{
    int x,y;
    float f;
    char text[22];

scanf("%d %2d %f %5s",  &x, &y, &f, text);
printf("%d  %d %f %s", x,y, f, text);

}

Input: 1 3456 5.6 web
Output: 1 34 56.000000 5.6

Query:

  1. Why did the argument/input for type string did not print?
  2. The variable 'y' read only 2 digits from the input value 3456 (as mentioned by the format specifier) but why did the unread digits(56) from the input 3456 were read and stored in the address of variable f of type float

The code says:

  • read an integer, the obvious way
  • read specifically a two-digit integer
  • read a float
  • read five characters of string

With an input of 1 3456 5.6 web , that is done as

  • obvious integer, reads "1"
  • two digit integer, reads " 34"
  • a float, reads "56"
  • five characters of string, reads " 5.6 "

The output should hence be (values with intermixed blanks from foramt string, using double quotes to visualise the different parts): "1"" ""34"" ""56.000000"" "" 5.6 " .

Notes:

  • there should be two blanks in the first blanks case, you report only one, frankly I assume a copy-paste on your part
  • the decimal point and the zeros are added for default format of outputting a float, I assume it matches your environment
  • the "5.6" again should have two leading blanks and a trailing blank which you do not report, again I assume a copy-paste mistake on your part
  • the "web" was never read, because of the restriction to five characters having already been filled with two blanks, two digits and a dot

The best way to understand it is to visualize it IMO.

So when it prompts you for input you enter 1 3456 5.6 web . Just imagine that stdin looks like this:

1 3456 5.6 web

The first format specifier is %d which just takes an integer and stores it into x . After %d :

 3456 5.6 web
x = 1, y = ?, f = ?, text = ?

Next format specifier is %2d , which means "take an integer, but the max digits will be 2, any digits after will be left untouched." So after %2d :

 56 5.6 web
x = 1, y = 34, f = ?, text = ?

Next is %f . Pretty self-explanatory, takes a float as input. However, since 56 is still left in stdin , it takes 56 as the input instead of 5.6 . So after %f :

 5.6 web
x = 1, y = 34, f = 56.0f, text = ?

Next is the last, %5s . It means "take a string, but take no more than 5 characters from input." However, it won't read web . Since " 5.6 " is still left before web , it'll take " 5.6 " (exactly 5 characters) instead as a string. So after %5s :

web
x = 1, y = 34, f = 56.0f, text = " 5.6 "

And web stays stuck in stdin , untouched. I think you get the rest.

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