switch with scanf one more input - c

I'd like to ask, if somebody can help me with the problem I have in my code. I mean while I want scanf 2 variables, code want one more input.. dunno whats wrong..
btw: I add part of the code
for(i;i<4;i++){
switch(i){
case 0:{
printf("Bod #1:\n");
scanf("%d%d\n",&x1,&y1);
printf("x1=%d y1=%d\n",x1,y1);
printf("working 1\n");
}
break;

Your problem lies with this line:
scanf ("%d%d\n", &x1, &y1);
specifically the \n in the format string. Referencing the standard (C11 7.21.6.2 The fscanf function /5 and keeping in mind that \n is a white-space character:
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.
So, as per the input values in your question, scanf starts processing the format string "%d%d\n".
The first format specifier %d needs more input and, when you enter 45\n, it skips any white-space (of which there is none) and loads the integer into its variable, leaving x1 == 45 and the input stream thus (^ represents the next read point):
45\n
^
The second format specifier %d skips white-space (the \n) and then needs more data so you enter 459\n. It then loads that integer into its variable, leaving y1 == 459 and the input stream thus:
45\n459\n
^
Here's where your problem starts. The final format specifier \n needs to read up to but not including the first non-white-space character. But it cannot tell that there's a non-white-space character at this point (since you may enter some more white-space), so it again needs more input which you provide: 54\n. This leaves the input stream as:
45\n459\n54\n
^
So now, the \n format specifier knows that the 5 in 54 is the first non-white-space character and it stops before reading that, giving:
45\n459\n54\n
^
That's the point at which scanf() returns since all format specifiers have been satisfied. Of course, the next call to scanf("%d%d...") will already have 54\n in the input stream so that will be used to populate x1. You'll still have to enter two more values before scanf() returns, the first which will populate y1 and the second which will satisfy the \n specifier.
Now, how to fix it. Well, that's pretty easy. As alluded to above, %d (and most other format strings) skip white-space before they attempt to read their data.
That means newlines will be automatically ignored if you just use "%d%d" as your format string, without the problmatic \n.
See, for example the following code:
#include <stdio.h>
int main (void) {
int x1, y1;
printf("Bod #1:\n");
scanf("%d%d",&x1,&y1);
printf("x1=%d y1=%d\n",x1,y1);
printf("working 1\n");
printf("\nBod #2:\n");
scanf("%d%d",&x1,&y1);
printf("x1=%d y1=%d\n",x1,y1);
printf("working 2\n");
return 0;
}
and sample run:
Bod #1:
45
459
x1=45 y1=459
working 1
Bod #2:
314159
271828
x1=314159 y1=271828
working 2

Related

What happen if scanf don't get enough characters from the standard input?

I know that the scanf function read the characters from standard input and it interpret them using the conversions specifications but what it will happen if there is some missing characters in the input stream ? it freeze until getting the next characters that it need to or it just ends ? For exemple :
the scanf call :
scanf ( " %d %d ", arg1, arg2) ;
the input stream : 14
Sorry for any mistakes in vocabulary. english is'nt my mother tong
What happen if scanf don't get enough characters from the standard input?
In general, scanning stops and scanf() returns the number of successful matching format specifiers. Unmatched input characters remains in stdin. The later specifiers' corresponding pointers' data are unchanged.
Yet there are many details - the above and below are over-simplifications.
scanf() stops under various conditions:
1) The happy path The format is fully satisfied. There is nothing more to the format string.
2) Input does not match the specifier anymore. Specifiers like "%d", "%f", "%99[^\n]", "%99s" consume input until some character that does not meet the specifiers needs - that character(s) is put back in the stream. If insufficient characters were read, scanning stops and the number of successful matching format specifiers is returned. If enough were read, scanning continues to the next part of the format. ("%n" is special - not addressed here).
int retval = sscanf("1abc", "%d", &i); // stop at 'a', return 1
int retval = sscanf("+1-", "%d%d", &i); // stop at '-', return 1
2) Input does not match a fixed character except white-space, scanning stops. Returning the number of successful matching format specifiers.
int retval = sscanf("1abc", "%da", &i); // stop at 'b', return 1
3) End-of-file occurs. scanf()returns the number of successful matched format specifiers.
4) Input error (rare). E.g. some internal mis-communication or trying to read from stdout. All pointers' data values are indeterminate. Return EOF.
5) Nothing matched, return EOF.
scanf ( " %d %d ", arg1, arg2) ;
With input "14" - end-of-file,
1) The first " " scans zero or more white-space. Never fails, scanning continues.
2) The first "%d" scans zero or more white-space then scans for numeric input consuming the "14". *arg1 is set to 14.
3a) End-of-file occurs. *arg2 unchanged. scanf() return 1.
With input "14\n" like above until 3a above.
3b) The 2nd " " scans zero or more white-space. It consumes '\n' and waits until a non-white-space is detected or end-of-file. scanf() is still processing and has not yet returned.
Given that you only input 14, scanf will wait for the remaining input specified in your format string or there is an input error, such as unexpected input or the input stream is closed.
Assuming the input stream is closed after 14.
The value of *arg2 will get unchanged.
But *arg1 will read fine; it will become 14.
Otherwise:
scanf will just wait until you input another integer. (and if you do not, your program will hang here forever)

C printf wont print before scaning next number

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

Break out of loop (do/while) by pressing a button [duplicate]

This question already has answers here:
What does space in scanf mean? [duplicate]
(6 answers)
Closed 7 years ago.
The following code gives the bizarre o/p as soon as I compile it.
main() {
char name[3];
float price[3];
int pages[3], i;
printf ( "\nEnter names, prices and no. of pages of 3 books\n" ) ;
for ( i = 0 ; i <= 2 ; i++ )
scanf ("%c %f %d", &name[i], &price[i], &pages[i] );
printf ( "\nAnd this is what you entered\n" ) ;
for ( i = 0 ; i <= 2 ; i++ )
printf ( "%c %f %d\n", name[i], price[i], pages[i] );
}
But if we give the space in the scanf statement before %c, it gives proper o/p.
Can anyone please explain me why is it so?
Update:-
If I am providing the input like this-
F
123.45
56
J
134
67
K
145
98
then my question is why not we are giving space before %f and space before %d? Why we need to give space before %c only?
Adding the space to the format string enables scanf to consume the newline character from the input that happens everytime you press return. Without the space, name[i] will receive the char '\n', and the real char is left to be misinterpreted by %f.
So, say your input is
a 1.0 2
b 3.0 4
c 5.0 6
The program sees it more like this:
a 1.0 2\nb 3.0 4\nc 5.0 6\n\377
That is, the line-breaks are actual characters in the file (and the \377 here indicates "end of file").
The first scanf will appear to work fine, consuming a char, a float, and an integer. But it leaves the input like this:
\nb 3.0 4\nc 5.0 6\n\377
So the second scanf will read the '\n' as its %c, unless you get rid of it first.
Adding the space to the format string instructs scanf to discard any whitespace characters (any of space ' ', tab '\t', or newline '\n').
A directive is one of the following:
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.
...
from http://linux.die.net/man/3/scanf
This sort of problem arises whenever you use scanf with %c in a loop. Because, assuming free-form input, newlines can happen anywhere. So, it's common to try to avoid the whole issue by using a two-tiered approach. You read lines of input into a buffer (using fgets); chop-off the silly newline characters; then use sscanf instead of scanf to read from the buffer (string) instead of straight from the file.
Incorrect input using %c
Consider the following snippet of code:
int main( ){
int x;
char y;
scanf("%d", &x);
scanf("%c", &y);
printf("%d %c", x, y);
}
Behavior: When you run the above program, the first scanf is called
which will wait for you to enter a decimal number. Say you enter
12(That’s ASCII ‘1’ and ASCII ‘2’). Then you hit the "enter" key to
signal the end of the input. Next the program will execute the second
scanf, except you will notice that the program doesn't wait for you to
input a character and instead goes right ahead to output 12 followed
by a ‘\n’.
Explanation:Why does that happen? Let’s look at the behavior of the
program step-bystep.
Initially there is nothing in the buffer. When the first scanf() is called, it has nothing
to read, and so it waits. It keeps waiting until you type 1,2, then "enter". Now what's in
the buffer are the character 1, the character 2, and the character ‘\n’. Remember that ‘\n’
signifies the end of input, once all fields have been entered, but it is also stored in the
buffer as an ASCII character. At this point scanf will read the largest decimal input from
the buffer and convert that to an integer. In this example, it finds the string "12" and
converts it to the decimal value twelve and puts it in x. Then scanf returns control back to
the main function and returns the value 1, for being able to convert one entry
successfully. In our example, we do not catch the return value of the scanf in a variable.
For robust code, it is important to check the return value of scanf( ) to make sure that the
user inputted the correct data.
What is now left in the buffer is ‘\n’. Next, the second scanf is
called and it's expecting a character. Since the buffer already has
the ‘\n’ character in it, scanf sees that, takes it from the buffer,
and puts it in y. That's why when you execute the printf afterwards,
12 and “enter” are printed to the screen.
Solution: Moral of the story is, enter is a character like any other,
and is inputted to the buffer, and consumed from the buffer by %c just
like any other ASCII character. To fix this, try using this code
instead:
int main( ){
int x;
char y;
scanf("%d", &x);
scanf("\n%c", &y); /* note the \n !! */
printf("%d %c", x, y);
}
**
How does this fix the problem?
** So you again type ‘1’,’2’,’\n’. The first scanf reads "1" and "2", converts that to the decimal twelve and leaves the ‘\n’ in the buffer.
The next scanf now expects a ‘\n’ at the beginning of the next input.
It finds the ‘\n’ in the buffer, reads it, and discards it. Now the
buffer is empty and scanf is waiting on the user to input a character.
Say the user inputs ‘c’, followed by the enter key. ‘c’ is now
assigned to y, NOT "enter". Therefore printf will output "12 c" to the
screen. NOTE: there is again a ‘\n’ sitting in the queue now. So if
you need to do another scanf for a single character, you will have to
"consume" that '\n' before taking another character in from the user.
This is not an issue for any other format specifier, as they all ignore white spaces before
the input.

Scanf Y/N and Save for Future Use

I want to ask a specific question and get a Y/N answer read in by the user. I will need to use the character Y or N to change the outcome of the next question eventually, which is why I need the character to be saved so I can retrieve it later. I don't want to use a string or a for/while loop. Also, why do I need to include the * after "%c*"?
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int avgTemp, lowestTemp, temperature;
char choice ='Y';
char decision ='N';
printf("What is the average temperature?\n");
scanf("%d", &avgTemp);
printf("What is the lowest temperature in last 24 hours?\n");
scanf("%d", &lowestTemp);
printf("Has the temperature been over 99 degrees F for more than 30 minutes?
Please answer Y for yes and N for no.\n");
scanf("%c*", &choice);
printf("choice is %c", choice);
return 0;
}
Also, why do I need to include the * after "%c*"?
%c* means to scan for a character and then a * (which it will discard). Maybe you meant %*c which means do the scan but discard it. You don't need either of them.
scanf is a very problematic function and should be avoided. Your program illustrates the problem. scanf does not read a whole line. scanf will only scan stdin up to what you asked for and then stop. This means extra input and newlines can sometimes be left on the input stream for the next unsuspecting scanf. From the man page...
Each successive pointer argument must correspond properly with each
successive conversion specifier (but see the * conversion below). All
conversions are introduced by the % (percent sign) character. The format string may also contain other characters. White space (such as blanks, tabs, or newlines) in the format string match any
amount of white space, including none, in the input. Everything else matches only
itself. Scanning stops when an input character does not match such a format character. Scanning also stops when an input conversion cannot be made (see below).
This makes it very easy to accidentally leave characters on the input buffer. Each of your scanf("%d") will read in the number and stop. This leaves a newline on the input buffer. This is fine for %d because...
Before conversion begins, most conversions skip white space
...but not for %c.
Matches a sequence of width count characters (default 1); the next pointer must be a pointer to char, and there must be enough room for all the characters (no terminating NUL is added). The usual skip of leading white space is suppressed. To skip white space first, use an explicit space in the format.
So you need scanf(" %c") to make it work at all.
scanf is to be avoided because it's very, very vulnerable to unexpected input. Try giving "foo" to the first question. All the scanf("%d") will silently fail. And scanf("%c") will read f.
Instead, read the whole line with getline (preferred as it handles memory allocation for you) or fgets and then use sscanf on the resulting string. This avoids all the above problems.

Why we need to put space before %c? [duplicate]

This question already has answers here:
What does space in scanf mean? [duplicate]
(6 answers)
Closed 7 years ago.
The following code gives the bizarre o/p as soon as I compile it.
main() {
char name[3];
float price[3];
int pages[3], i;
printf ( "\nEnter names, prices and no. of pages of 3 books\n" ) ;
for ( i = 0 ; i <= 2 ; i++ )
scanf ("%c %f %d", &name[i], &price[i], &pages[i] );
printf ( "\nAnd this is what you entered\n" ) ;
for ( i = 0 ; i <= 2 ; i++ )
printf ( "%c %f %d\n", name[i], price[i], pages[i] );
}
But if we give the space in the scanf statement before %c, it gives proper o/p.
Can anyone please explain me why is it so?
Update:-
If I am providing the input like this-
F
123.45
56
J
134
67
K
145
98
then my question is why not we are giving space before %f and space before %d? Why we need to give space before %c only?
Adding the space to the format string enables scanf to consume the newline character from the input that happens everytime you press return. Without the space, name[i] will receive the char '\n', and the real char is left to be misinterpreted by %f.
So, say your input is
a 1.0 2
b 3.0 4
c 5.0 6
The program sees it more like this:
a 1.0 2\nb 3.0 4\nc 5.0 6\n\377
That is, the line-breaks are actual characters in the file (and the \377 here indicates "end of file").
The first scanf will appear to work fine, consuming a char, a float, and an integer. But it leaves the input like this:
\nb 3.0 4\nc 5.0 6\n\377
So the second scanf will read the '\n' as its %c, unless you get rid of it first.
Adding the space to the format string instructs scanf to discard any whitespace characters (any of space ' ', tab '\t', or newline '\n').
A directive is one of the following:
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.
...
from http://linux.die.net/man/3/scanf
This sort of problem arises whenever you use scanf with %c in a loop. Because, assuming free-form input, newlines can happen anywhere. So, it's common to try to avoid the whole issue by using a two-tiered approach. You read lines of input into a buffer (using fgets); chop-off the silly newline characters; then use sscanf instead of scanf to read from the buffer (string) instead of straight from the file.
Incorrect input using %c
Consider the following snippet of code:
int main( ){
int x;
char y;
scanf("%d", &x);
scanf("%c", &y);
printf("%d %c", x, y);
}
Behavior: When you run the above program, the first scanf is called
which will wait for you to enter a decimal number. Say you enter
12(That’s ASCII ‘1’ and ASCII ‘2’). Then you hit the "enter" key to
signal the end of the input. Next the program will execute the second
scanf, except you will notice that the program doesn't wait for you to
input a character and instead goes right ahead to output 12 followed
by a ‘\n’.
Explanation:Why does that happen? Let’s look at the behavior of the
program step-bystep.
Initially there is nothing in the buffer. When the first scanf() is called, it has nothing
to read, and so it waits. It keeps waiting until you type 1,2, then "enter". Now what's in
the buffer are the character 1, the character 2, and the character ‘\n’. Remember that ‘\n’
signifies the end of input, once all fields have been entered, but it is also stored in the
buffer as an ASCII character. At this point scanf will read the largest decimal input from
the buffer and convert that to an integer. In this example, it finds the string "12" and
converts it to the decimal value twelve and puts it in x. Then scanf returns control back to
the main function and returns the value 1, for being able to convert one entry
successfully. In our example, we do not catch the return value of the scanf in a variable.
For robust code, it is important to check the return value of scanf( ) to make sure that the
user inputted the correct data.
What is now left in the buffer is ‘\n’. Next, the second scanf is
called and it's expecting a character. Since the buffer already has
the ‘\n’ character in it, scanf sees that, takes it from the buffer,
and puts it in y. That's why when you execute the printf afterwards,
12 and “enter” are printed to the screen.
Solution: Moral of the story is, enter is a character like any other,
and is inputted to the buffer, and consumed from the buffer by %c just
like any other ASCII character. To fix this, try using this code
instead:
int main( ){
int x;
char y;
scanf("%d", &x);
scanf("\n%c", &y); /* note the \n !! */
printf("%d %c", x, y);
}
**
How does this fix the problem?
** So you again type ‘1’,’2’,’\n’. The first scanf reads "1" and "2", converts that to the decimal twelve and leaves the ‘\n’ in the buffer.
The next scanf now expects a ‘\n’ at the beginning of the next input.
It finds the ‘\n’ in the buffer, reads it, and discards it. Now the
buffer is empty and scanf is waiting on the user to input a character.
Say the user inputs ‘c’, followed by the enter key. ‘c’ is now
assigned to y, NOT "enter". Therefore printf will output "12 c" to the
screen. NOTE: there is again a ‘\n’ sitting in the queue now. So if
you need to do another scanf for a single character, you will have to
"consume" that '\n' before taking another character in from the user.
This is not an issue for any other format specifier, as they all ignore white spaces before
the input.

Resources