简体   繁体   中英

C - How scanf inputs work and how it iterates in loops?

I know the basics of scanf(); requiring a conversion specifier % and an address to the variable to store the input value &.

While doing an assignment, there was a task that involved inputting an arbitrary number of values, one example would be: 5 4 3 2 1

Into scanf, and then print out number of symbols corresponding to the integer typed (eg. '?'), so it would display the terminal as:

5 4 3 2 1
?????
????
???
??
?

In this case I had put the scanf in a while loop as so:

int i, num;
while(scanf("%d",&num)==1){
   printf("%d",num);
   for (i=0; i<num; i++){
      printf("?");
   }
   printf("/n");
}

I am totally confused how scanf reads multiple integers in one input line (5 4 3 2 1) when many sources has specified that scanf only takes one integer until it reads a whitespace. From looking at this, my understanding is that the whitespace separating the integers indicate a new iteration following the previous integer? When I tried to trace how printing works, it printed as:

5 4 3 2 1
5?????
4????
3???
2??
1?

...So my question is how does scanf 'save' all these integers in one line to 'num' and print EACH of the corresponding symbols to the values given AFTER input? Wouldn't integers be replacing the previous in the variable without an array?

Sorry if this question does not make sense - still quite new to coding. Thank you!

Your understanding of scanf is true, scanf only takes one integer until it reads a whitespace.

What makes you confused here is how the algorithm works. Your algorithm first reads the integer 5 and prints "immediately" five ? . It continues to read 4, print four ? , read 3, print three ? , and so on.

scanf stores the line in an internal buffer. If the buffer is not empty, it tries to read from the buffer and remove the portion that was successfully read; if the buffer is empty it waits for user input. On the first iteration of your outer loop ( while ), the buffer is empty. You input "5 4 3 2 1", so the buffer contains that. The first sscanf("%d",&num) reads the first integer from the buffer, which is 5; the buffer now contains " 4 3 2 1". On the second iteration you read 4, and the buffer will be " 3 2 1". This goes on until the buffer is exhausted. At this point your program continues; it just waits for more input.

Wouldn't integers be replacing the previous in the variable without an array?

There's no array required here at all.

The scanf() function takes the value (assuming white spaces included) and all of them are saved one by one into the variable num . If you use a debugger (suppose using GDB) and set a breakpoint in while() , you'll get to know by stepping into that the variable num is changed in each iteration and the for loop runs till num is reached.

An example of two iterations using a debugger is provided below (focus on num on the left corner):

Iteration 1:

迭代 1

Iteration 2:

迭代 2

scanf 'reads' characters from the standard input stream stdin (if there is nothing there yet it prompts the user to type something to be added to it), and converts them to a format depending on the conversion specifiers used in the format string.

You can think about stdin as a sequence of characters in the memory, and every time the user types something in the terminal and presses Enter what was typed is added to the stdin .

So in your case, when you type 5 4 3 2 1 and presses Enter in the terminal, stdin will receive the sequence of characters "5 4 3 2 1\n" (notice that the new line character was added when you pressed Enter).

Then the scanf("%d",&num) , which is expecting only 1 decimal integer number, 'reads' and 'consumes' from stdin the relevant characters that form one continuous decimal integer number.

In this case 5 is read the first time scanf is executed, and " 4 3 2 1\n" is left in the stdin . Then as the condition is satisfied the loop statements are executed. And the second time scanf is executed the leading space is discarded by the %d specifier and 4 is read, leaving " 3 2 1\n" in the stdin . And so on until no decimal integers numbers can be read from the stdin ...

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