IF "for loop" is like this,
for(i=0;i<5;i++)
{
scanf("%d",&a[i]);
}
Then,
Input can be given either as,
1
2
3
4
5
Hitting Enter Every time for the next Input.
OR
1 2 3 4 5
With space character between different input values.
Now, How does this thing work?
I mean if loop is running,
then how does it recognizes that Input is given for the next loop cycle wihtout hitting the Enter key.
How does this thing work?
This works because scanf() reads only till a space or newline or tab is encountered.
So, when you give input 1 2 3 4 5, at the first iteration scanf() reads 1 and a space is encountered and scanf() terminates keeping the value 1 to a[0]. At the next iteration2` is read the same way.
The scanf (and family) function with the "%d" format reads white-space delimited input. If the white-space is a newline or a single space doesn't matter.
The Enter key simply tells the input stream system that input is ready (stdin which is used by scanf is line buffered by default), exactly what that input is doesn't matter.
Related
i am new to c and have used python before. This whole buffer overflow stuff is really breaking my mind.
#include <stdio.h>
int main(){
char str1[3];
while(true){
scanf("%2s", str1);
printf("test\n");
}
}
This is a little code i've written to test the syntax and the stdio library. I was really suprised when the program outputted "test" multiple times, depending on how many characters i entered. So for example, when I entered two characters, it printed "test" two times. Can anyone please tell me why this is happening and how I can fix it?
You can figure out what happens by modifying your code as follows:
#include <stdio.h>
int main(){
char str1[3];
while( 1 ){
scanf("%2s", str1);
printf("test: %s\n", str1);
}
}
which simply prints the contents of the str1 alongside of the "test" string.
Here is an example output for an input string of 1234567:
1234567
test: 12
test: 34
test: 56
test: 7
The scanf("%2s", str1); statement reads two characters from the stdin and assings them to the str1. The read characters are "popped" from the input stream, i.e., they are removed. If the stdin happens to contain more characters, the excess ones are left untouched. Therefore, for the given input, when the first scanf is returned, the str1 containes 12\0, and the stdin contains 34567.
Since these are in the infinite loop, the code repeats, scanf gets called again, reading the first two characters from the stdin again, only this time finds 34.
And the process repeats, untill there are no characters left on the stdin, then the scanf waits for the user input, presumably as you would have expected.
Basically, scanf keeps reading instead of waiting for user input, since the stdin already contains something to read.
So for example, when I entered two characters, it printed "test" two times.
This on the other hand, does not make sense, as it should be printing "test" for N/2 times, rounded up, where N is the number of characters you enter.
There is not much that I can suggest for "fixing this", since it is not really clear what you are expecting. But if you want to get rid of the remaining characters in the stdin, you can check this.
You need to clear your input buffer as per this answer
Otherwise, you'll read from the stdin, print it, jump back to the loop head and continue reading, if there is still something in the buffer.
Each time through the loop, scanf("%2s", str1) reads at most 2 non-whitespace characters from the input stream. If there are more than 2 non-whitespace characters available in the stream, the loop will continuously call scanf (and printf) until scanf blocks waiting for data. If the input stream contains ffff\n and has not yet been closed (eg, a user is entering data interactively from a tty), the first 2 calls to scanf will immediately return and printf will be called twice. The 3rd call to scanf will block until more data is available, or the stream is closed, or there is an error.
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.
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...
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:
Iteration 2:
Does the input buffer gets cleared after scanf reads?
#include <stdio.h>
int main(void)
{
int a, b;
scanf("%d", &a);//I inputted 3
scanf("%d", &b);//I inputted 4
}
So when I gave the input 4 was 3 present in the input buffer?
So when I gave the input 4 was 3 present in the input buffer?
No, the 3 was consumed.
You cannot re-read it (as int or otherwise).
If you input "3<enter>" the 3 is consumed and the buffer contains just the "<enter>". You then type "4<enter>" which is added to the buffer. The 2nd scanf (*) consumes the initial enter and the 4 leaving "<enter>" for the next input operation.
(*) the conversion specifier "%d" skips optional leading whitespace and (tries to) converts the rest of the input to integer (if no errors occur).
So when I gave the input 4 was 3 present in the input buffer?
No, it wasn't.
scanf() reads (and consumes) from the standard input until a match the specified format (in your case an integer) is found. That format is converted and consumed as well.
I am following the exercises in the C language book. I am in the first chapter where he introduces loops. In this code:
#include <stdio.h>
/* copy input to output; 1st version */
int main() {
int c, n1;
n1 = 0;
while ((c = getchar()) != EOF) {
if (c == '\n') {
++n1;
}
printf("%d\n", n1);
}
}
In here I am counting the number of lines. When I just hit enter without entering anything else I get the right number of lines but when I enter a character then hit enter key the loop runs twice without asking for an input the second time. I get two outputs.
this how the output looks like:
// I only hit enter
1
// I only hit enter
2
// I only hit enter
3
g // I put char 'g' then hit enter
3
4
3 and 4 print at the same time. why is 4 printing after the loop has been iterated already? I thought the loop would restart and ask me for input before printing 4.
The getchar function reads one character at a time. The number of lines will be printed for every character in the input read by getchar, whether that character is newline or not, but the counter will only be incremented when there is a newline character in the input.
When you enter g then the actual input that goes to the standard input is g\n, and getchar will read this input in two iterations and that's the reason it is printing number of lines twice.
If you put the print statement inside the if block then it will print only for newline characters. If you put the print statement outside the loop, then it will only print the count of the number of lines at the end of the input.
To be clear this is the terminal that you are dealing with.
By default, the terminal will not get input from the user \n is entered. Then the whole line is placed in the stdin.
Now as I said earlier here the program is not affected by the buffering of stdin. And then the characters will be taken as input and it is processed as you expect it to be. The only hitch was the terminals buffering - line buffering.
And here from standard you will see how getchar behaves:-
The getchar function returns the next character from the input stream pointed to by stdin. If the stream is at end-of-file, the end-of-file indicator for the stream is set and getchar returns EOF. If a read error occurs, the error indicator for the stream is set and getchar returns EOF.
Now what are those characters - those charaacters include \n - the \n is what you put in the terminal and then to stdin via pressing the ENTER. Here earlier you were entering the characters earlier which were \n. This time you entered two characters. That's why the behavior you saw.
I got this piece of code
#include<stdio.h>
#include <stdlib.h>
int main()
{
int i;
int number, S;
float MO;
S = 0;
for(i=0;i<10;i++)
{
printf("AAA %d\n", i );
scanf("%d\n", &number);
S = S + number;
}
MO = S/10;
printf("%d , %f \n",S , MO );
return 0;
}
when the execution starts, AAA 0 is printed.I then give my first number.After that, i am expecting to see AAA 1 , but this will be printed only after i give my second number.
Checked this here
C/C++ printf() before scanf() issue
but seems i can get none of these solutions work for me
The answers claiming that this has something to do with flushing input or output are wrong. The problem has nothing to do with this. The appearance of the \n character at the end of the scanf() template string instructs scanf() to match and discard whitespace characters. It will do so until a non-whitespace character is encountered, or end-of-file is reached. The relevant part of the C11 Standard is §7.21.6.2 5:
A directive composed of white-space character(s) is executed by
reading input up to the first non-white-space character (which remains
unread), or until no more characters can be read. The directive never
fails.
In OP's case, a second number must be placed in the input stream so that the first can be assigned. The second number then remains in the input stream until the next call to scanf(). In the case of the example given by Stephan Lechner, taking input from a file, there is a number in the input stream after each number to be assigned, until the last number (if there are exactly ten numbers), and then the EOF causes scanf() to return. Note that OP could also have signalled EOF from the keyboard after each input. Or, OP could enter all numbers on one line, with an extra number to signal end of input:
1 2 3 4 5 6 7 8 9 10 11
The solution is simply to remove the \n from the end of the scanf() template string. Whitespace characters at the end of such a template string are tricky, and almost never what is actually desired.
Just remove the \n from the scanf format string:
scanf("%d", &number);
"\n" waits for non-white-space. Instead use scanf("%d", &number) #Michael Walz and check its return value.
Let us break down scanf("%d\n", &number);
"%d" Scan for numeric text. This specifier will allow leading white-space. Once some non-numeric character is found, put that character back into stdin. If valid numeric text for an integer was found, convert to an int and save to number.
"\n" Scan and discard 0 or more white-spaces such as '\n', ' ', and others. Continue scanning until non-white-space is encountered, put that character back into stdin.
Now return the number of fields scanned (1).
Notice step 2. User had to type in data after the Return or '\n' to get scanf() to return.
The issue is with the buffering of stdout which doesn't force a flush unless a \n is in the output or fflush is called specifically