Reputation:
Why if I write some other letter or number(not y\n) the order
printf("\nWould you like to play again? (y/n):");
run twice?
int ans= 0,i=1;
do
{
printf("\nWould you like to play again? (y/n):");
ans = getchar();
if (ans=='y')
{
printf("yyyyyyyyyyy");
i = i-1;
}
else if ( ans == 'n')
{
printf("nnnnnnnnnnn");
i=i-1;
}
else
{
printf("not y or n");
}
}
while(i);
Upvotes: 0
Views: 191
Reputation: 1547
the problem is that when you go into the program again in the do while there is already an answer in memory. getchar()
adds a \n and that is what stays. to avoid this you can make ans a character (char) meaning that it will be reading the ascii table; (y = 121 and n = 110). Char does not place a \n (new line) after it receives the input, to make sure this happens you have to leave a space before %c like so scanf(" %c", &ans);
this means that ans is receiving a int.
#include<stdio.h>
#include<stdlib.h>
int main(void){
char ans;
int i = 1;
do
{
printf("\nWould you like to play again? (y/n):");
scanf(" %c", &ans);
if (ans == 121){
printf("yyyyyyyyyyy");
i = i - 1;
}
else if ( ans == 110){
printf("nnnnnnnnnnn");
i = i - 1;
}
else{
printf("not y or n");
}
}
while(i);
}
Upvotes: 0
Reputation: 388
Another solution:
char c = 'x'; // Initialize to a character other than input
while( c != 'y' || c != 'n') { // You can also use strchr as @Olaf mentioned
printf ("\nPlay again (y/n): ");
c = getchar ();
}
Upvotes: 0
Reputation: 12263
This is overcomplicated. As you stated in a comment, you just want to loop until y
or no
has been typed. No need for an extra variable. In general for such problems it is a bad idea to use a counter. More failsafe is using a bool
flag.
A good approach without helper variable would be:
int ans; // no need to initialise, as it is set before the first read
do {
printf("Play again?");
do {
ans = getchar();
} while ( ans == `\n` );
...
} while ( (ans != EOF) && !strchr("yYnN", ans) );
See strchr
. I added tolerance for uppercase letters.
Note that you always check for EOF, too. As that cannot be represented as a char
, you have to test seperately and first (otherwise the conversion in strchr
might yield unexpected results.
Also note fflush
ing an input stream (which can be found in some code on the internet) is undefined behaviour - don't use it. Even if some libraries tolerate it, they might not behave as expected (which is implied by undefined behaviour). Flushing in general as the semantics of "writing/sending out" data. Input normally is "dropped" (and there is nofdrop
function.
Edit: Added inner loop to drop newline characters. Without that the loop will run twice after an invalid character entered. This assumes you have to enter one character per line.
Upvotes: 2
Reputation: 206697
No matter what letter you type before you press Enter, the line
c = getchar();
still leaves the newline character in the input stream.
If the character is something other than y
and n
, that call gets executed without waiting for you and the newline character gets assigned to c
. Hence, you see output from the following lines twice.
printf("\nWould you like to play again? (y/n):");
and
printf("not y or n");
You need to add code to ignore the rest of the line from the input after
c = getchar();
Add a function:
void ignoreRestOfLine()
{
int c;
while ( (c = getchar()) != EOF && c != '\n');
}
and call it as:
c = getchar();
ignoreRestOfLine();
Upvotes: 0
Reputation: 7030
Probably because your getchar
call is picking up the newline from your input. So if you press 'X', the first time through the loop ans
is 'X' and the newline was buffered. The second time through the loop ans
is '\n'.
You can put a loop around your input call like this:
do
ans = getchar();
while (isspace(ans));
Upvotes: 2
Reputation: 17051
The while(i)
is effectively the same as while(i != 0)
. If you enter something other than y
or n
, the else
block runs, and does not change the value of i
. Since i=1
before the loop, i
is nonzero if you enter something other than y
or n
. Try:
else
{
printf("not y or n");
i = i-1; // <---- new line
}
Upvotes: 2