while loop and getchar() - c++

I have the simple program below that I wrote for a college course. I know it doesn't really do anything, but it's just an assignment for a course.
The part that I can't figure out, is why doesn't the outer loop work?
The user needs to press '1' to continue, and any other key the program exits.
However, it still doesn't continue if the user presses '1' and instead exits anyway.
I tried adding a cin.clear() before cin >> repeat, but that doesn't work.
I also tried playing around with cin.ignore(), but that didn't seem to help either.
Any ideas?
Thanks
int main()
{
int repeat = '1';
stack<char> cstr;
char c;
while (repeat == '1')
{
cout << "Enter in a name: ";
while (cin.get(c) && c != '\n')
{
cstr.push(c);
}
cout << "\n Enter another name? 1 = Continue, any other key to exit the program";
cin >> repeat;
repeat = getchar();
}
}

There is nothing at all wrong with your code. It seems to be working fine for me.
EDIT: Sorry it doesn't work until you remove the getchar. Forgot to mention that. Simple way of finding out the error is to just display the value of the variable repeat to see what the value is and where it is going wrong.
Screenshot to show you that your codes work
Everything seems to be working fine. I would like to comment on your program structure though. For small programs like this it's ok but always best to practice the logical way. For questions like this you should implement the do while loop instead of the while loop so that it goes in without checking and then accepts the user input and checks with the post condition. Example below.
char repeat;
do
{
//Your codes in here
}while (repeat == '1');
It is more logical to use this method instead unless your question specifies you to use while loop. Anyhow hope this helps.

Run this . it will solve your problem somehow repeat=getchar was making repeat=10.
int main()
{
char repeat = '1';
stack<char> cstr;
char c;
while (repeat == '1')
{
cout << "Enter in a name: ";
cin.ignore();
while (cin.get(c) && c != '\n')
{
cstr.push(c);
}
cout << "\nEnter another name ? \nPress 1 to Continue : ";
cin >> repeat;
cout << endl;
}
system("pause");
}

The line cin >> repeat is tring to read an integer from the keyboard because repeat is a variable of type int. However, you are verifying if the integer read from the keyboard is equal to 49 (the ASCII code for the character '1'), which is not what you want. A solution would be to replace the line
int repeat = '1';
with
int repeat = 1;
and also replace
while (repeat == '1')
with
while (repeat == 1)
because then you are comparing the integer read from the keyboard with the integer 1 (rather than the character '1'). Also, at the end of the loop you read input from the keyboard and store it in repeat but then you immediately read input again and store that value in repeat, replacing its previous value. To solve this, replace the line
repeat = getchar();
with
getchar();
and that should do it.

cin >> repeat;
it reads repeat as int. (1 is not equal '1')
repeat = getchar();
It reads int code of special char '\n' - symbol end of line.
You must use
char repeat = '1';
Or write
int repeat = 1;
and not use getchar()

Related

How to bail out of a while loop once a certain value is inputted into a variable

I'm making a program that uses a while loop in C++. Here is my code so far:
int userInput = 0;
while (userInput != 'Z')
{
cout << "Please enter the homework score: ";
cin >> userInput;
homeworkScores.push_back(userInput);
if (userInput == 'Z') {
userInput = 'Z';
}
}
The problem im having is whenever I type Z, the loop keeps printing "Please enter the homework score: " over and over without stopping. I've defined homeworkScores as a vector earlier in the code. How can I make it stop the loop once userInput == 'Z'? Thanks in advance!
The problem you are facing, is that cin is trying to read an integer, but you provide a character in the input. cin will only ask for another input, once the input is empty, you can try this by supplying more than one integer to your code:
Please enter the homework score: 2 27 12 8
will input all four numbers and print "Please enter the homework score: " 4 additional times.
If you provide it with a character, it will not remove it from the input, so whenever "cin" is reached, it will see "Z" in the input, and continue.
You can use answers like provided here How to catch invalid input in c++? for your input sanitation, but it will not make "Z" work as a stop.
The easiest way is to chose an invalid score like -1 instead of Z, end on any invalid input or try to read a string on failure to read an int.
A simple way to exit a loop is by using the break statement.
if (userInput == 'Z') {
userInput = 'Z';
break;
}
Other ways would be to set your exit condition to resolve as false, which I think is causing some issues for you.
EDIT: As #Ganea Dan Andrei noted, reading a char from cin into an integer will cause the cin::fail() to return true. This can be reset by calling cin.clear(), which will allow you to make further inputs.
userInput is an integer, and so 'Z' would have to equal the ASCII equivalent of its char value, which is 90. The way you're doing it should shouldn't work. Instead, try making userInput a char, and then convert it to an integer so you can push it back into your vector. This might look like:
char userInput = '';
while (userInput != 'Z')
{
cout << "Please enter the homework score: ";
cin >> userInput;
homeworkScores.push_back(userInput - '0'); //Are you sure you want to push a 'Z'?
if (userInput == 'Z') {
userInput = 'Z';
break;
}
userInput = ''; // Reset your input so it doesn't keep getting pushed new values
}
What happens here is userInput - '0' is subtracting the ASCII values of your chars, and leaving you with their integer value. There are other ways to do this, but this is a commonly used way.

If you enter the desired input twice, it outputs twice?

Heres my example:
while (response == 'y')
{
playOneGame();
cout << "Great! Do you want to play again (y/n)? ";
cin >> response;
}
And if you type in: yy
It prints the output twice:
"Great! Do you want to play again (y/n)? Great! Do you want to play again (y/n)? "
I would just like to understand why. This program is written in C++ if that matters. Thanks.
Since you are comparing it to a char (result == 'y'), I'm assuming result is also a char.
The cin operation is going just read one char, and leave the second one on the input buffer. Then, the next time through the loop, it reads the second 'y' without any additional user input required.
If you want to be sure there is nothing left in the buffer, read until you get a line terminator. Or you can read into a string:
string response = "y";
// continues on anything that starts with lowercase 'y'.
// exits on anything else.
while (response.length() >= 1 && response[0] == 'y') // length check maybe unnecessary?
{
playOneGame();
cout << "Great! Do you want to play again (y/n)? ";
cin >> response;
}
It is not clear the type of response, but I assume it is char.
char response;
while(response=='y'){
playOneGame();
cout << "Great! Do you want to play again (y/n)? ";
cin >> response;
}
cin reads all the chars until you stop sending chars to it. Simply, cin gets whole terminal line so when you press 'yy', while loop runs twice.
If loop runs twice and prints the message two times:
1. It doesn't start game again.
2. Even, it starts the game, when it is over, for the second y, it does starts game again without asking.
Modify your code to read one char and continue. You can use getche() to get one char and continue.
This is exactly what you need. Apply the code below to your real case.
#include<iostream>
#include<limits>
using namespace std;
int main()
{
char response = 0;
while(cin >> response){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "You enterd: " << response << endl;
}
return 0;
}
Here is the explanation:
Why would we call cin.clear() and cin.ignore() after reading input?

while statement is unable to read the correct char input

hi i am new to c++ and i dont understand why my while statement doesnt work now. it was working when i tried to do it earlier.
Full code is available at: http://pastebin.com/aeH5fKwh
basically here is the while loop (i excluded all the unnecessary parts, i left the inside of the while loop intact for viewing purpose)
int main()
{
unsigned int seed;
char input;
bool done;
for (int round = 0; round < 5; round++)
{
done = false;
cout << "\nEnter seed: ";
cin >> seed;
cout << "\nRound 1" << endl;
while(!done)
{
cout << "\nDo you wish to draw another card [y][n]: ";
cin >> input;
while (input != 'y' && input != 'n')
{
cout << "Invalid input! Please enter [y][n]!" << endl;
cin >> input;
}
if (input == 'y')
{
dealExtra(playerHand, deck, gameInfo);
cout << "Your cards are ";
printHand(playerHand, gameInfo.playerCardCount);
}
else
done = true;
}
}
cout << endl;
return 0;
}
when i try entering anything that is not 'y', 'n', it will tell me that my input is invalid. But when i try to enter 'y' or 'n', it kinda just ignored it and nothing else happened.. i checked with cout statement and found that it manage to get into the if (input == 'y') statement, but it doesnt seem like it is doing anything else. Everything was fine till 20 minutes ago and i really couldnt figure out whats wrong.
Edit: i ran another test using "cout << '[' << input << ']' << endl;".. it seems like the program is able to get my first input, but then it just hangs there afterwards.. what i get is something like:
Do you wish to draw another card [y][n]: y
[y]
y
y
y
y
I compiled this on linux terminal using g++
if extra codes is needed, i'll edit and add them.. thanks!
When you ask for input from the console, most implementations buffer characters until a newline key is pressed.
After the newline is received, the first character of the buffer is returned. The newline still remains in the buffer as well as any extra characters.
In your case, the second cin >> input statement will read the newline from the buffer.
As an experiment, try entering "frog" and single step through your program. This should illustrate the case of residual characters in the buffer.
Try cin.ignore(1000, '\n') after the first cin >> input. The ignore method will eat up any remaining characters in the buffer until the newline is found.
Make below statements inactive
dealExtra(playerHand, deck, gameInfo);
printHand(playerHand, gameInfo.playerCardCount);
and check if it works, then try making one of the above statements active alternately to find out in which function the flow is getting lost. And so on.
If you feel lazy to run a debugger, and plan to use cout<< statements to find a hanging call, you should flush you cout:
( cout << "I am here and going to hang" ).flush() ;
Otherwise you can't see recent output just because it's still in the output buffer. Try this and you well might see what call hangs your program.
You have an infinite loop inside checkComputerHand:
bool done = false;
while(!done)
{
if(sum == 11 && checkAce == true)
{
computerHand[aceLocation].value = 11;
done = true;
}
if(sum > 11 && checkAce == true)
{
computerHand[aceLocation].value = 1;
done = true;
}
// What if checkAce wasn't true? Infinite loop!
}
Also, the first two lines of newGame do not make any sense:
void newGame(Card playerHand[], Card computerHand[], Statistics &gameInfo)
{
playerHand = '\0';
computerHand = '\0';
// ...
}
Array parameters are silently rewritten by the compiler as pointer parameters. So all you're doing is assigning the null pointer to those local pointers. Probably not what you intended...

Prompting to run the program again: fixing if they put an invalid statement in

Morning!
My question: I state in the program to enter Y for yes and N for no. If the user enters yes, no, or a random string, it will say that it's an invalid input and ask again. But say the user enters "yes yes yes", it will output the invalid statement three times. How could I resolve this?
I also need to do something about the boolean because it serves no purpose as I break the loop if they say n, but nevermind that.
Here's a fragment of my code:
bool done = true;
string ans;
try {
coeff input = readCoeffs();
results result = equSolver(input);
outResults(input, result);
while (done == true) {
cout << "Would you like to run the program again (Y to run again, N to close)? ";
cin >> ans;
if (ans == "Y" || ans == "y") {
coeff input = readCoeffs();
results result = equSolver(input);
outResults(input, result);
}
else if (ans == "N" || ans == "n") break;
else cout << "Invalid input. \n";
}
}
catch (const char* msg) {
cerr << msg << endl;
}
It should be
while(done == false)
Done should be initialized to false, and in your loop, set done to true when they enter N or n. It's somewhat a style question, but it's usually best to avoid breaks unless there's a REALLY good reason.
For your invalid input issue, you are using
cin >> ans;
This is broken by whitespace, so in put of "l m n o p" is going to make the program say "invalid input" twice, then exit. Look into using getline if you want to process by line instead.
The answers are simple enough.
1.
You can use while(true) and get rid of the done flag. or instead of using break;, flip the done flag. (Btw, I think you either misnamed the variable, or you flipped the boolean values... it still works but semantically it makes no sense.)
2.
cin only reads up to the next whitespace, which can be a space. If you want to read the whole line, you need to use getline. So instead of
cin >> ans;
use
getline(cin, ans);
EDIT: I fixed which getline is used. Should be correct now.
Two possibilities that I came up with:
Use getline(cin, ans)
Set the limit to the amount of characters read as follows:
char input[100];
cin.getline(input,100);

Validating a double in c++

I'm completely new to coding, so please keep this in mind before commenting.
So I've been trying to get into coding for a while, and today I went to the library
and picked up a book called "programming in c++". I've written some basic programs,
but I have gotten stuck at one point, I have no idea how to create a function that
makes sure that when the user is prompted for a double, what they enter is valid.
(If the user enters a character like 'k', the program just breaks).
I searched here and on the net, and there are some answers, but they are more along
the line of "here's a line of code that works, insert x, y, z, into it". And I don't
have enough experience to know what to do. So here is a sample that is a mix of code
from another question, and me failing to try to make it work in my program:
#include <iostream>
#include <stdio.h>
using namespace std;
double GetDouble () {
double x;
cin >> x;
int valid = 0;
while (valid == 0) {
if (x == double) {
return x;
break;
} else if (x != double) {
cout << "Invalid Input! Please input a numerical value." << endl;
cin.clear();
while (cin.get() != '\n') ; // empty loop
}
}
return x;
}
Now what I want it to do is to use "cin << x" to get a user input for x, and
then make sure that x is a double, and I'm failing quite hard at this. If
someone could explain this to in a manner that clarifies each operation,
I would be truly grateful. For example, I don't know what the break function does,
and what the cin.clear(), and cin.get() do. (I know this is a duplicate, but the
answers on the other question does not at all address what I'm confused about,
thank you for taking time to read & answer this! :)
This seems a close analog to your code that (mostly) works:
double GetDouble () {
double x;
cin >> x;
// ver1: while( cin.fail() ) // or !cin.good() no trailing char check.
while( cin.fail() || (cin.peek() != '\r' && cin.peek() != '\n'))
{
cout << "Invalid Input! Please input a numerical value." << endl;
cin.clear();
while( cin.get() != '\n' ); // or cin.ignore(1000, '\n');
cin >> x;
}
return x;
}
First of all, double is a keyword so you don't need to use it in a conditional statement.
Secondly, you can use the cin>>x in a while loop and then process x , a sample code is given below:
while(cin>>x)
{
//process
}
whenever you use anything in a while statement, it first checks it's validity.
if for example user enters a character the condition will evaluate to false and you can then tell this to the user. In this way you can run the loop till the time user enters correct input.
As for the function of break keyword, it gets you out of a loop, for ex
for(int i=10; i>0; i++)
{
// do something
}
will keep on running forever, but suppose you rewrite the code as:
for(int i=10; i>0; i++)
{
if(i==15)
break ;
}
the loop will end as soon as the value of i reaches 15
Something like so:
double getDouble(const string& askMessage = "Please Enter a number: ",const string& errorMessage = "Please enter a valid number: ", const int numberOfTrials = 10){
double userInput = 0.0;
bool isValidInput = false;
int trials = 0;
do{
cout << endl << askMessage;
if(cin >> input) break;
else{
cin.clear(); //EDIT thanks ebyrob, forgot about this.
std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
std::cout << errorMessage;
}
}while(!isValidInput || trials < numberOfTrials);
return userInput;
}
use it like so
const double d1 = getDouble();
const double d2 = getDouble("Please Enter a number: ", "Error! Enter a valid number: ", 1000);
Break breaks out of a loop (in this case, a while)
cin.clear() clears the cin buffer of all chars.
cin.get() gets a single character from cin (probably standard in).