Boggy B
Boggy B

Reputation: 171

C++ - Skipping code after first run-through?

I have a do-while loop, shown below

do
{
    dimensions = NULL;

    printf("=======================================\nDo you want to multiply in 2 dimensions, or 3?\n\n");

    scanf("%c", &dimensions);

    ... //do stuff

    printf("\nEnter r to repeat, return to terminate\n");
    scanf("%c", &key);
    scanf("%c", &key);
}
while(key == 'r');

On the first run, it executes fine. The problem however is when it runs through the code again after the user enters 'r' and hits return. It'll take you to the first printf("==== etc., but won't allow the user to do anything, it'll go straight back to the second printf("\nEnter...

I stepped through the code to see what was going on, and on a second run through the program just skips the scanf( and all following code for absolutely no reason. Initially I thought it was because 'dimensions' wasn't being set to a value that doesn't run the following methods - but I have, and even if that were the case, the program would run the methods instead of skipping them without user input.

Am I missing something? Is scanf( not enough to stop the program once it's already been used?

Upvotes: 0

Views: 333

Answers (3)

Loki Astari
Loki Astari

Reputation: 264331

What is happening now

To make the buffer flush you need to enter

r<enter>

Hitting <enter> flushes the buffer. So the input buffer now contains two characters.

r\n

So the first scanf will read r
The second scanf will read \n

So by the time you reach the while key has a value of \n. The test fails and the loop is not repeated. So you should remove the second scanf() reading into key.

So you remove the second scanf. Now what happens?

User types

r<enter>

This leaves the input buffer with:

r\n

The scanf() read r into key. The loop repeats correctly. But when we get back to the scanf(). The input buffer still has \n character in the buffer. So the scanf() immediately reads this value and the loop exists as it should have.

how you should fix it.

Ask for Y/N answer and validate that the input is correct.

std::string line;
std::getline(std::cin, line);
while (line != "Y" && line != "N")
{
    std::cout << "Hey cluts enter a correct value. Y/N\n";
    std::getline(std::cin, line);
} 

Upvotes: 0

Your problem is that when your program gets input from the console with scanf, it reads the data from the keyboard into the input buffer, then values are taken out of the buffer and placed into the locations you provide to scanf. The issue is that when scanf reads a character, it also reads the \n into the buffer, then upon being called again, it reads the second character that was placed into the buffer (without asking you for more input - because why would it? It already HAS things in the buffer).

So there are two solutions: one - use fflush on stdin like so: fflush(stdin). Second - write a while loop that clears out characters one by one from the input buffer: while (getchar() != '\n' );

EDIT: For more reading, see How to clear input buffer in C?

Upvotes: 1

Pete Becker
Pete Becker

Reputation: 76245

Think it through: "the user enters 'r' and hits return", then the program reads the 'r' and repeats. What's left in the input buffer? There were two keys pressed, and the code only read the first one.

That's also the reason that the code needs two calls to scanf. The first clears the extra character out of the input buffer and the second reads the new character.

Upvotes: 0

Related Questions