cin wont work in loop - c++

Ok so im trying to learn c++, and i was making a simulation but the cin wont work for me :(
void Simulation::initialize(){
cout<<"Choose number of players: " <<endl;
cin>> numberOfPlayer;
string name;
int accurasy;
int life;
for(int index=0; index <=numberOfPlayer;++index){
cout<<"Enter name, accurasy and life for player"<<index +1 <<": " <<endl;
cin>>name;
cin>>accurasy;
cin>>life;
Kombatant comb(name,accurasy,life);
vect->push_back(comb);
}
}
This is the code that wont work for me. Im trying to add players to the simulation. Everything works as expected until i get in to the for loop. For some reason it only works in the first looping until i get to life. Then it skips the life input and every input after that (every input in all the loops). Anyone have any ideas what the problem is ?

It's because the last newline is still in the input buffer. So when you loop the input of the name will see the newline and give you an empty input.
You have to tell the input stream to explicitly skip it:
// all your input...
// Skip over the newline in the input buffer
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')

Related

cin.fail not working when numbers and letters entered

I am working on a simple data validation as part of inputting numbers to an array. Right now it is working for the most part with the exception of one case - when I enter a number followed by a letter, the error message that I created it thrown, but the number is still entered into the array. Further confusing me is that it is functioning as intended when I compile the program in Xcode, but the issue I'm describing only shows up when I compile the program with g++. Any thoughts would be very appreciated. Here is my function which I think is giving me the issue.
float getInput()
{
float input;
std::cin >> input;
if (std::cin.fail())
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "type char/str not allowed, enter int" << '\n';
return getInput();
}
else
return input;
}
Got it sorted out. Basically, this is not the time to be using recursion. I put the if statement in a while loop, added a second cin to the end of the loop, and moved the return out of the loop. That took care of it. Thanks for the suggestion to use a loop instead.

Avoid bad user input (string when what's asked is an integer)

I have an infinite while loop, where the user is asked for a number.
My problem is very simple: If the input is a string, I want to re-ask user for input, outputting the message "Enter a valid choice: ".
I searched, and looks like I should check for cin.fail(), then call cin.clear() and cin.ignore().
Here's my code:
int main() {
int choice;
bool failed = false;
while (true) {
if (failed) cout << "Enter a valid choice: ";
else cout << "Enter a number: ";
cin >> choice;
if (cin.fail()) {
cin.clear();
cin.ignore();
failed = true;
}
}
return 0;
}
However, this doesn't really fix my problem. Of course, it isn't printing infinitely, but for each letter extra letter , it prints another "Enter a valid choice:"
Seems like I need to call cin.ignore() for each extra letter.
Any other way of doing this?
You have an infinite loop because you are not breaking the loop even when valid input is enter. Is that what you really want? If so, at the least, you are not resetting the failed flag in valid input.
More importantly, when invalid input is entered, you are not ignoring everything that was enteted, you are only ignoring 1 char at a time. That is why you see extra prompts.
Try this instead :
int main() {
int choice;
while (true) {
cout << "Enter a number: ";
while (!(cin >> choice)) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Enter a valid choice: ";
}
}
return 0;
}
The reason it is printing so many times is because you are only clearing the state of cin, but aren't clearing the input buffer. You can do so in multiple ways:-
Use fflush(stdin) to clear the input buffer.This is the C method and can be done by including cstdio header.
Use the cin.ignore to ignore all characters in the current input stream. You can do this by replacing the line cin.ignore() which ignores a single character by this code cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') which ignores the entire line. For this you need the limits header.
Finally you can do the same with a simple loop like while (cin.get() != '\n'){continue;} which ignores all characters till new line.
Also another approach to the same problem is to take the input in form of a string and use the strtol() or the isdigit() functions to check if the input is valid.
By the way the infinite loop is because you have not used the break statement to terminate the loop. So you can avoid this by adding
if(!failed)
break;
Also you need to change the state of Failed at the entry of each loop by adding
failed=false;
at the start of the loop body.

Clear entire line from cin instead of one character at a time when the user enters bad input

I have a question on some commands for cin. I'm still very new to c++ so bear with me.
I'm doing a simple calculation program where the user inputs a value and the program does a calculation with the input. I'm attempting to create a loop that checks the input to ensure the user inputted and number. After some research I found that using cin.clear and cin.ignore will clear the previous input so the user can input a new value after the loop checks to see if its not a number. It works well, except when the user inputs a word larger then 1 letter. It then loops and removes each letter one at a time until the previous cin is cleared. Is there a way to remove the entire word rather then one character at a time? I feel I have incorrectly interpreted what the cin commands actually do.
Here is the code in question:
//Ask the user to input the base
cout << "Please enter the Base of the triangle" << endl;
cin >> base;
//A loop to ensure the user is entering a numarical value
while(!cin){
//Clear the previous cin input to prevent a looping error
cin.clear();
cin.ignore();
//Display command if input isn't a number
cout << "Not a number. Please enter the Base of the triangle" << endl;
cin >> base;
}
I think you could get the answer in many ways on the net. Still this works for me:
#include <iostream>
#include <limits>
using namespace std;
int main() {
double a;
while (!(cin >> a)) {
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Wrong input, retry!" << endl;
}
cout << a;
}
This example is simpler than the one linked in the comments since you are expecting input from the user, one input per line.

C++ problems involving getline() and a loop

I am working an a school assignment and am beating my head against a wall right now trying to figure out why my program is not behaving as I'd like it to!
int main(){
string input;
char choice;
bool getChoice(char);
string getInput();
CharConverter newInput;
do{
cout << "Please enter a sentence.\n";
getline(cin, input);
cout << newInput.properWords(input) << endl;
cout << newInput.uppercase(input) << endl;
cout << "Would you like to do that again?\n";
cin >> choice;
} while (getChoice(choice) == true);
return 0;
}
This program works fine on the first round, but I am having a problem when getChoice() == true, and the do while block is looped a second time. On the second loop, the program asks for me to enter a sentence again, but then just jumps to "Would you like to do that again?" without allowing user input or outputting the results of the properWords() and uppercase() functions. I suspect that there is something about getline that I do not understand, but I have yet to find it through my googling. Any help out there?
edit: there was a mistake in my original explanation.
This is because reading input with getline does not mix well with reading input character-by-character. When you enter the Y/N character to indicate if you want to proceed or not, you also press Enter. This puts \n in the input buffer, but >> does not take it from there. When you call getline, the \n is right there, so the function returns an empty string right away.
To fix this, make choice a std::string, use getline to read it, and send the first character to getChoice function, like this:
string choice;
...
do {
...
do {
getline(cin, choice);
} while (choice.size() == 0);
} while (getChoice(choice[0]));

While Loop Repeats 4 Times

I'm trying to only accept integers as input and loop through it at the same time as a sort of validation. The problem is, when a user enters something along the lines of "Two" the while loop goes through the input 3 different times before asking the user again. Is there a way to prevent this from happening and just skip the 3 iterations?
cout << "Enter Student ID: ";
while(!(cin >> id))
{
cout << "\nERROR: Please enter a Positive Whole Number" << endl;
cin.clear();
cin.ignore ();
cout << "Enter Student ID: ";
}
You can use this.
cin.ignore (std::numeric_limits<streamsize>::max (), '\n') ;
It would skip all the lines and you wont get extra loop iterations, no matter how many invalid characters you enter.
The reason for your while loop iterating is that the stream is not being extracted completely so by just using this line
cin.ignore (std::numeric_limits<streamsize>::max (), '\n') ;
the loop will iterate only for once because no matter how much big input you give it will be extracted. Cin.ignore() only removes the one character from the stream.
In your case if you enter "two" then after firs iteration only 't' will be extracted and the input would be "wo" for the second iteration. But by adding this line stream would be empty in the second iteration and will take input from user.