user5724207
user5724207

Reputation:

this function run too many times

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

Answers (6)

learningbyexample
learningbyexample

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

Erobrere
Erobrere

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

too honest for this site
too honest for this site

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 fflushing 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

R Sahu
R Sahu

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

Turn
Turn

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

cxw
cxw

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

Related Questions