Store data in array from input [duplicate] - c

This question already has answers here:
'printf' followed by 'scanf' requires pressing ENTER key twice to accept input
(2 answers)
Why does scanf ask twice for input when there's a newline at the end of the format string?
(7 answers)
Closed 5 years ago.
I'm beginner in C. Please dont mind if my question is lame. In this program which i have written, when I use 'for' loop first time , I expect only 3 values is stored in an array but it stores 4 values and in next 'for' loop as expected show 3 values.
My Question is why in 1st 'for' loop it takes 4 values instead of 3?
#include<stdio.h>
void main()
{
int marks[3];
int i;
for(i=0;i<3;i++)
{
printf("Enter a no\n");
scanf("%d\n",(marks+i));
}
for(i=0;i<3;i++)
{
printf("%d\n",*(marks+i));
}
}

\n in scanf was the problem
#include<stdio.h>
int main()
{
int marks[3];
int i;
for(i=0;i<3;i++)
{
printf("Enter a no\n");
scanf("%d",(marks+i));
}
printf("\nEntered values:\n");
for(i=0;i<3;i++)
{
printf("%d\n",*(marks+i));
}
return 0;
}
Reason:
I expect only 3 values is stored in an array but it stores 4 values
and in next 'for' loop as expected show 3 values. My Question is why
in 1st 'for' loop it takes 4 values instead of 3?
First: No, it only stores 3 number but not 4 numbers in array marks[].
Second: interesting to understand loop runs only for three times for i = 0 to i < 3. The for loop runs according to condition. More interesting code is stuck in scanf() as described below:
Your confusion is why you have to enter four numbers, its not because you loop runs 4 times but its because scanf() function returns only when you enter a non-space char (and after some enter press you inputs a number symbol that is non-space char).
To understand this behavior read manual: int scanf(const char *format, ...);:
A sequence of white-space characters (space, tab, newline, etc.; see
isspace(3)). This directive matches any amount of white space,
including none, in the input.
Because in first for loop's, in scanf() you have included \n in format string, so scanf() returns only if press a number enter (or a non-space key).
scanf("%d\n",(marks+i));
^
|
new line char
What happens?
Suppose input to program is:
23 <--- because of %d 23 stored in marks[0] as i = 0
<enter> <--- scanf consumes \n, still in first loop
543 <--- scanf returns, and leave 542 unread,
then in next iteration 543 read by scanf in next iteration
<enter>
193
<enter> <--- scanf consumes \n, still in 3rd loop
<enter> <--- scanf consumes \n, still in 3rd loop
123 <--- remain unread in input stream

remove \n
and i can be created in the if statement as for (int i = 0; i < 3; i++) {}

Related

Why does having scanf & printf in a loop cause this output

The program in question:
#1:
int main(void) {
int size;
scanf("%d", &size);
int v[size];
for(int i = 0; i < size; ++i) {
scanf("%d", &v[i]);
printf("the %d-th element is : %d\n",i, v[i]);
}
return 0;
}
O/P:
5
6 7 8 9 10 11
the 0-th element is : 6
the 1-th element is : 7
the 2-th element is : 8
the 3-th element is : 9
the 4-th element is : 10
My question: Why does it seem like the program does all the print statements after your input?
So does the program kind of 'hold' the print statements to display them after you press <Enter> for a new-line? Is there a better explanation of this behavior somewhere?
**Edit after #dbush's answer**
I need a bit of a clarity on this: so let's say the `size = 5` & my input is `6 7 8 9 10` so I'm asuming the first `scanf` in the loop reads the `6 ` part then reads/stores the data and then passes the rest of the content that's in the input buffer to the next `scanf`'s leaves the rest of the input data in the `input buffer`
Then the program goes towards the printf statement stores that output in some sort of a buffer then it loops back to the 2-nd scanf and that reads the 7 part and all of this goes till the 10<enter> part, now the final scanf reads/stores 11 and since there's a newline, the programs decides that it no longer needs to read from the input buffer and now outputs the rest of the contents from the output buffer to the console.
Is this how it goes or are there some inaccuraries in this analogy?
Edit #2: I found this good blogpost explaining what goes on with scanf's & the input buffer, together with #dbush & #Weather Vane answers to completely answer any doubts I've had regarding this
When reading from a terminal, nothing gets sent to scanf until you press ENTER.
So in your case, you have 6 strings which look like numbers in the input buffer. The first scanf reads just the first number, because that's what its pattern is looking for and leaves the rest in the input buffer. Then the program continues by calling printf, and because the string ends with a newline it gets printed immediately. When the program then loops back around to scanf, there's already data in the input buffer so it reads what's there and returns immediately, and the cycle continues.
So only the first call to scanf is waiting for input from the user, while the others are reading what's already in the input buffer, and the printf calls are having their output go to the terminal immediately since the string to print ends with a newline.

Getting newline before print statement - C

The runs stored by N batsmen of a cricket team is passed as the input to the program. The program must print the name of the batsman who scored the highest runs.
#include <stdio.h>
int main()
{
int n;
scanf("%d",&n);
int run[n],maxIndex=0;
char name[n][100];
for(int i=0;i<n;i++)
scanf("%[^,],%d",name[i],&run[i]);
for(int i=0;i<n;i++){
if(run[i]>run[maxIndex])
maxIndex=i;
}
printf("%s",name[maxIndex]);
return 0;
}
Input:
5
BatsmanA,45
BatsmanB,42
BatsmanC,12
BatsmanD,9
BatsmanE,78
Output:
BatsmanE
The issue is I'm getting a newline at first before the print statement. Like,
Output:
BatsmanE
The issue is I'm getting a newline at first before the print statement.
That is becasue %[^,] reads the prior line's left-over '\n' first.
scanf("%d",&n); reads the "5" and stores 5 into n. '\n' remains in stdin.
scanf("%[^,],%d",name[i],&run[i]); reads the "\nBatsmanA,45" and stores "\nBatsmanA" into name[0], then reads the ",", then reads "45" and stores 45 into run[0].
To read a line of user input, research fgets().
First of all, if you want to use scanf for string reading, you should make sure you can't get more characters than the string can handle. For that you can use width sub-specifier:
scanf("%99[^,],%d", name[i], &run[i]);
About the '\n' you got on the beginning of that string, that's because "%[^,]"
keeps it from the previous scanf, just add * that will read and discard that thing:
scanf("%*[\n]%99[^,],%d", name[i], &run[i]);
but as you can see, the format string becomes a lot less readable now...
Best thing would be if you just used "%99s" and rely on spaces instead of ',':
scanf("%99s%d", name[i], &run[i]);
now you just separate the values with space in the input and get the same result:
Input:
5
BatsmanA 45
BatsmanB 42
BatsmanC 12
BatsmanD 9
BatsmanE 78
but at that point I'd personally prefer just separating the format into 2 "scanfs":
scanf("%99s", name[i]);
scanf("%d", &run[i]);
And again, you will get the same result

Why it is asking for 4 input instead of 3? [duplicate]

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Closed 4 years ago.
Why it is asking for 4 input instead of 3 ?
I have used only 3 scanf in my program.
This is a program about finding smallest and largest number among 3 variables.
Please Help...
#include <stdio.h>
int main()
{
int first, second, third;
printf("Enter 3 integers for compare:");
scanf("%d\n",&first);
scanf("%d\n",&second);
scanf("%d\n",&third);
if((first>second) && (first>third))
printf("First number is the largest\n");
else if((second>first) && (second>third))
printf("Second number is the largest\n");
else if((third>second) && (third>first))
printf("\nThird number is the largest\n");
if((first<second) && (first<third))
printf("First number is smallest\n");
else if((second<first) && (second<third))
printf("Second number is smallest\n");
else if((third<second) && (third<first))
printf("Third number is smallest\n");
return 0;
}
Lets take your last call to scanf:
scanf("%d\n",&third);
The "\n" at the end of the format string means the scanf function will read and discard any white-space after the input, but it can't know when the white-space ends until there is something which is not a white-space character. That means you need to enter some extra input for scanf to be satisfied.
So the simple solution is to just don't have the newlines in your scanf format strings.

how many times this loop will be executed?

I write this code, which takes an integer number (t) as input from the user. A loop will be executed just 't' times. But I find that it runs for (t-1) times. For example, if I give input 3, it runs only 2 times. Can anyone please explain why this is happening?
I tried and used scanf("%s", &str), it works, but then I can't take a string as input that contains spaces.
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
char str[100];
gets(str);
printf("%s\n", str);
}
return 0;
}
scanf("%d", &t) consumes only the numeral in the input stream and leaves the remaining characters. When you enter a numeral and press enter, there is a newline character after the numeral.
The first gets reads this newline and returns a string that is empty except for the newline. The first iteration of the loop prints this blank line.
Loop is iterating 3 times as it should.But it seems that it is iterating 2 times only because of the reason that the \n character left behind by gets in the buffer is read in second iteration.
For first iteration, when you enter a string and the press Enter, the \n character go to the buffer with the string. gets stop reading when it encounters \0, leaving \n in the buffer. On next iteration this \n (non printable character) is read by gets and then printed to terminal.
NOTE: Never use gets function. It is no longer is the part of standard C. Use fgets instead.
I guess you can also use the scanf function to resolve your problem that the string is not accepting anything after a SPACE . Also, the loop is running (t-1) times because the buffer is not being cleared due to the use of gets() . In order to resolve this, you can use the getch() function to clear the buffer. The following code should work I guess,
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
char str[100];
scanf("%[^\n]c",&str);
printf("%s\n", str);
getch();
}
return 0;
}
In this code, the getch() will clear the buffer by accepting the useless value. Also as far as scanf() is considered, the ^ inside the scanf tells the function that it needs to take the input till the character after the ^ is encountered which in this case is an escape sequence of NEW LINE . I have tried using some small words as well instead of the newline and it has worked as well. Hope this clears your issue :)

loop executes more than needed [duplicate]

This question already has answers here:
Scanf skips every other while loop in C
(10 answers)
Store data in array from input [duplicate]
(2 answers)
Closed 8 years ago.
I have the following code:
#include<stdio.h>
#include "commonf.h" //So, this is the way you include from a directory?
void main(){
println("Welcome to Number Guesser v 0.1 ");
println("Think of a number between 0 and 100 (and please, make it an integer!)");
println("Legend: Y=Yes B=Bigger than that S= Smaller than that");
int guessed=0;
float curnum=100.0;
char cursign='?';
while(cursign!='y'){
if(cursign=='?' || cursign=='s'){
curnum=curnum/2;
}
else if(cursign=='b'){
curnum=curnum+curnum/2;
}
else{
printf("You are wrong. Stop it. %c . TEESST",cursign);
}
char askstring[4096];
sprintf(askstring,"%s%f%s","Is your number ",curnum," ? (y/b/s)");
println(askstring);
scanf("%c",&cursign); //Scanf has to expect a new line for some reason.
}
}
(I pasted all of it, since I am a c noob)
If the code looks like this, the loop will execute twice per user input, once with cursign= to whatever the user entered, and once with it equal to \n.
If I change the scanf line to
scanf("%c\n",&cursign);
It asks for the first input twice, then works as a charm. What's the problem, and what should I do?
Change this scanf("%c\n",&cursign); to this scanf(" %c",&cursign);. This will eat up the trailing newline character.
Also as per standard main should return an int (even though this is not the reason for your problem). According to C standards main should be int main(void) or int main(int argc, char* argv[])
When you enter a character like y and hit the ENTER key, a character (which you entered) and a character (which is the enter keystroke - the newline character) gets placed in the input buffer. The first character gets consumed by the scanf but the newline remains in the input buffer so what happens is that the next time you enter something there 3 characters newlinechar + 'y' + newlinechar. So that makes scanf behave funny.
This is a great link from Grijesh - C Printf and Scanf Reference

Resources