When a user enters spaces in between digits to create a reference string it throws everything off and will even carry numbers over to the next cin. If however they have letters in between and no spaces it works fine. The assignment was for a page replacement sim.
Code (this is only the part of the code that should effect my problem):
void main()
{
bool again = false;
bool reuse = false;
bool valid;
int use;
int refLength;
vector<int> ref(0);
vector<frame> frames(0);
string refString;
string user;
//ask how long the user wants the ref string to be
do{
valid = false;
while (!valid&&!reuse)//take choice of ref string
{
cout << "How long do you wish the reference string to be? ";
if (!(cin >> refLength))
{
cin.clear();//.clear and .ignore keep cin from errors and forced infinite loop repeating following cout
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "The length must be enter as an integer value between ";
valid = false;
}
else
{
cout << "You have chosen to have a Ref string of " << refLength << " length " << endl;
valid = true;
}
}
valid = false;
while (!valid&&!reuse)
{
cout << "Do you want to enter a ref string or randomly generate one" << endl;
cout << "of your chosen length? Enter 1 to generate and 2 to input the string ";
if (!(cin >> use) | (use<0 || use>2))
{
cin.clear();//.clear and .ignore keep cin from errors and forced infinite loop repeating following cout
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "You must enter an integer between 1 and 2";
}
else
{
valid = true;
if (use == 1)
{
make(ref, refLength);
}
else
{
cout << "please enter a ref string of chosen length entering" << endl;
cout << "fewer digits will cause 0's to be added. Entering more" << endl;
cout << "will cause those past the chosen length to be dropped " << endl;
cout << "any letters will be ignored but spaces throw things off" << endl;
cout << "Also all entries must be single digit integers (0-9) " << endl;
cin >> refString;
make(ref, refLength, refString);
}
use = 0;
}
}
cout << endl;
/*for(int i=0;i<ref.size();i++)
{
cout<<ref[i]<<" ";
}*/
valid = false;
while (!valid)
{
cin.clear();
//errors ********************************************88
cout << "How many frames do you want (1-7) ";
if (!(cin >> use) | (use<0 || use>7))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "You must enter an integer between 1 and 7 ";
valid = false;
}
else
{
valid = true;
setUpFrames(use, frames);
use = 0;
}
}
valid = false;
while (!valid)
{
cout << "Enter 1 for FIFO or 2 for LRU pageRep algo or 3 for Optimal";
if (!(cin >> use) | (use<0 || use>3))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Must be int between 1 and 3";
}
else if (use == 1)
{
cout << endl << "# of Page Faults ";
cout << FIFO(ref, frames);
valid = true;
}
else if (use == 2)
{
cout << endl << "# of Page Faults ";
cout << LRU(ref, frames);
valid = true;
}
else
{
cout << endl << "# of Page Faults ";
cout << Optimal(ref, frames);
valid = true;
}
}
cout << endl;
cout << "do you want to try again ? Enter y for yes anything else for no" << endl;
cin >> user;
if (user == "y")
{
again = true;
cout << "do you want to use the same reference string? y for yes anything else for no" << endl;
cin >> user;
if (user == "y")
{
reuse = true;
}
else
{
reuse = false;
}
}
else
{
again = false;
}
} while (again);
}
If you want cin/cout interaction word/line by word/line use getline, otherwise confusion will arise.
Related
So I am currently working on a program in c++. I have written the following function. The line where it says "//code here" is where my issue is. Basically the program allows the user to create their own quiz txt file. For the question "How many questions should the quiz have?" the user will enter a number that represents the amount of questions. The issue arises when the user input will have to be validated.
Can anyone help me create a loop that does the following?
makes sure the user enters only numbers.
makes sure the numbers entered are greater than 1.
gives the user an error message if they entered a non digit.
gives the user an error message if they entered a number less than 2.
the program validates if the user just presses the enter key.
Once that is all sorted out the program will set NumberOfQuestions equal to the user input after converting it to an int.
void WriteOutQuestions(string &QuizName)
{
ofstream WriteOut;
string filename = "";
string userInput = "";
int numberOfQuestions;
char userInputChar = '0';
bool IncludeCommments = false;
cout << "Name your file\n";
getline(cin, filename);
cout << "Now give your new quiz a title\n";
getline(cin, QuizName);
cout << "How many questions should the quiz have?\n";
getline(cin, userInput);
//code here
numberOfQuestions = stoi(userInput);
cout << "The quiz will contain " << numberOfQuestions << " questions." << endl;
cout<< "Would you like to include comments in any of the choices?\n";
cout << "[Y/y for yes N/n for No]\n";
getline(cin, userInput);
if (userInput == "y" && userInput == "Y")
IncludeCommments = true;
else
cout << "Comments disabled by user...\n";
WriteOut.open(filename + ".txt");
if (!WriteOut)
{
cout << "The file was not found...\n";
}
else
{
cout << "File was read!\n";
}
WriteOut << QuizName << endl;
WriteOut << numberOfQuestions << endl;
for (int i = 0; i < numberOfQuestions; ++i)
{
cout << "What is question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "Q" << i + 1 << " " + userInput << endl;
cout << "What is choice A for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "A) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice A for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice B for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "B) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice B for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice C for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "C) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice C for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice D for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "D) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice D for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "Which choice is the right one? [A, B, C or D]\n";
getline(cin, userInput);
while (userInput != "a" && userInput != "A" && userInput != "b" && userInput != "B" &&
userInput != "c" && userInput != "C" && userInput != "d" && userInput != "D")
{
cout << "Only A-D is accepted\n";
}
userInputChar = userInput[0];
if (userInputChar > 96)
{
userInputChar -= 32;
}
userInput = userInputChar;
cout << "userinput contains " << userInput << endl;
cout << "userinputchar contains " <<userInputChar << endl;
WriteOut << userInput << endl;
}
WriteOut.close();
}
first of all you need to change the && in the below code to || to run the code the code correctly
if (userInput == "y" && userInput == "Y")
IncludeCommments = true;
else
cout << "Comments disabled by user...\n";
and coming to the validation you can maintain a flag variable after taking userinput
cout << "How many questions should the quiz have?\n";
getline(cin, userInput);
int length=userInput.length(); //gives the length of string entered
int flag=0; //flag variable
for(int i=0;i<length;i++)
{
if((!(userinput[i]>='0'&&userinput[i]<=9))||isspace(s[i])) //i am
considering space is not a problem
{
flag=1;
}
}
if(flag!=0)
{
cout<<"error:Non digit is entered"<<endl
}else
{
int numberofquestions = stoi(userinput);
if(numberofquestions<=1){
cout<<"error:number less than 2 is entered"<<endl;
}
}
There are so many options that it is difficult to make a good recommendation.
I will show you several solutions. The first part has always the same approach:
We run a do loop
First we instruct the user, what to do
Then we read the input
Then we, check, if all are digits
If we have all digits, then we convert to a number
and check, if the number is greater than 1
If we find an error, we loop again. Let`s look at the options in the code below
Index based for loop and compare with character digits
Index based for loop and use of isdigit function
Range based for loop and use of isdigit function
all_of algorithm and use of isdigit function
regex. Will also handle empty lines
Extened regex. Will also handle empty lines AND will check if number > 1
Options 1-4 need an additional check for an empty line. User presses just enter.
Please see code with all options:
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
#include <regex>
int main() {
// We try to get input from the user and run a loop as long as it is not OK
bool inputIsOK{};
// This is the number of questions that we want to read
int numberOfQuestions{};
// Ask for valid input from user
do {
// Assume valid input
inputIsOK = true;
// Instruct user
std::cout << "\nHow many questions should the quiz have? Enter a number > 1.\n";
// Read complete line from the user
std::string line{};
if (std::getline(std::cin, line)) {
// Check, if all characters are valid (digits)
// Option 1 -------------------------------------------------------------------
// Index based for loop and compare with character digits
for (size_t i{}; i < line.length(); ++i) {
if (line[i] < '0' || line[i] > '9') {
inputIsOK = false;
std::cerr << "\nError 1: Please enter digits only\n";
break;
}
}
// Option 2 -------------------------------------------------------------------
// Index based for loop and use of isdigit function
for (size_t i{}; i < line.length(); ++i) {
if (not std::isdigit(line[i])) {
inputIsOK = false;
std::cerr << "\nError 2: Please enter digits only\n";
break;
}
}
// Option 3 -------------------------------------------------------------------
// Range based for loop and use of isdigit function
for (const char c : line) {
if (not std::isdigit(c)) {
inputIsOK = false;
std::cerr << "\nError 3: Please enter digits only\n";
break;
}
}
// Option 4 -------------------------------------------------------------------
// all_of algorithm and use of isdigit function
if (not std::all_of(line.begin(), line.end(), isdigit)) {
inputIsOK = false;
std::cerr << "\nError 4: Please enter digits only\n";
}
// Option 1-4 -----------------------------------------------------------------
// For option 1 to 4 you need to additionally check for empty line
if (inputIsOK && line.length() == 0) {
inputIsOK = false;
std::cerr << "\nError 5: Please enter digits only\n";
}
// Option 5 -------------------------------------------------------------------
// regex. Will also handle empty lines
if (not std::regex_match(line, std::regex("\\d{1,6}"))) {
inputIsOK = false;
std::cerr << "\nError 6: Please enter digits only (max 6)\n";
}
// Option 6 -------------------------------------------------------------------
// Extened regex. Will also handle empty lines AND will check if number > 1
if (not std::regex_match(line, std::regex(R"([2-9]|([1-9][0-9]{1,6}))"))) {
inputIsOK = false;
std::cerr << "\nError 7: Please enter number > 1 (Max 6 digits)\n";
}
// End Option -----------------------------------------------------------------
// Check, if number is > 1
if (inputIsOK) {
numberOfQuestions = std::stoi(line);
if (numberOfQuestions < 2) {
inputIsOK = false;
std::cerr << "\nError 8: Number too small. Enter number > 1\n";
}
}
}
else {
std::cerr << "\nError: General problem with input\n";
inputIsOK = false;
std::cin.clear();
}
} while (not inputIsOK);
return 0;
}
You can choose whatever option you want.
However. I would not use one of the above.
I would use the IOstream facilities and directly read an unsigned integer. If the input is wrong, the state of std::cin will goto fail and indicate the problem.
So, you could use that instead:
#include <iostream>
#include <limits>
int main() {
// We try to get input from the user and run a loop as long as it is not OK
bool inputIsOK{};
// This is the number of questions that we want to read
unsigned int numberOfQuestions{};
// Ask for valid input from user
do {
// Instruct user
std::cout << "\nHow many questions should the quiz have? Enter a number > 1.\n";
// Get input. Directly as number
inputIsOK = (std::cin >> numberOfQuestions) && (numberOfQuestions > 1);
// In case of error. Show message
if (not inputIsOK) {
std::cerr << "\nError 1: Wrong input\n";
std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
} while (not inputIsOK);
return 0;
}
The ignore function will delete all the trash taht maybe still in the input buffer.
I was writing this code for training, and I'm in a problem where if my user write his name followed by a space and something else, the program will mess up my flow. So it's easier if you try the little program and when it ask for name, put like "Robert Red". The problem occurs just when you put something else after the space, if you input just "Robert" all goes good.
This is the code:
// Description: This is a simple replica of the Japanese game Rock, Paper and
// Scissors.
// Author: Ernesto Campese
// Last Update: 11/04/2018
// Version: 0.0.1
#include "std_lib_facilities.h"
int main() {
string username = "";
char userinput;
int rounds = 0;
int wins = 0;
int draws = 0;
int loses = 0;
int user_secret = 0;
vector<string> options = {"Paper", "Scissors", "Rock"};
cout << "Enter your name: ";
cin >> username;
cout << "Welcome " << username << ", this is the game of Rock, Paper and Scissors.\n";
cout << username << " how many rounds you want to do? ";
cin >> rounds;
if (rounds <= 0) {
cout << "You need to play at least one round!\n";
rounds++;
}
cout << "The game is based on " << rounds << " rounds, you versus the CPU.\n";
cout << "Are you ready? (y/n): ";
cin >> userinput;
if (userinput != 'y') {
cout << "\nThank you.\nProgram Terminated by " << username;
return 0;
}
for(int i = 1; i <= rounds; i++) {
// Title of the rounds
if (i == 1) {
cout << "\nLet's start the first round!\n";
} else {
cout << "Round n. " << i << " begins!\n";
}
// USER makes a move
cout << "Which is your move? (r,p,s): ";
cin >> userinput;
cout << '\n' << username << " says... ";
switch (userinput) {
case 'r':
cout << "Rock\n";
user_secret = 2;
break;
case 'p':
cout << "Paper\n";
user_secret = 0;
break;
case 's':
cout << "Scissors\n";
user_secret = 1;
break;
default:
cout << "something weird...\n";
break;
}
// CPU makes a move
int cpu_secret = rand() % 3;
cout << "CPU says... " << options[cpu_secret] << "!\n";
// The program calculates the result.
if (user_secret == cpu_secret) {
draws++;
cout << username << " and the CPU draws!\n\n";
} else if (user_secret == 0 && cpu_secret == 2) {
wins++;
cout << username << " wins!\n\n";
} else if (user_secret == 1 && cpu_secret == 0) {
wins++;
cout << username << " wins!\n\n";
} else if (user_secret == 2 && cpu_secret == 1) {
wins++;
cout << username << " wins!\n\n";
} else {
loses++;
cout << username << " lose!\n\n";
}
}
cout << "\n\nBattle End!\n";
if (wins > loses) {
cout << username << " won the battle!\n";
} else if (loses > wins) {
cout << username << " lost the battle!\n";
} else {
cout << username << " draws the battle!\n";
}
cout << "Thank you " << username << "!\n";
}
You can try it here: Try me
Thank you!
operator>> stops reading input when it finds a whitespace character.
Use std::getline() to read user input with spaces.
Example using your code:
cout << "Enter your name: ";
getline(cin, username);
If you want the user to be able to type in a name that has spaces in it, use std::getline() instead of operator>>:
getline(cin, username);
Otherwise, if you want the user to enter only 1 word for the name, and you want to ignore anything else the user may enter, use std::cin.ignore():
#include <limits>
...
cin >> username;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Alternatively, you can use std::getline() to read a line, and then use std::istringstream with operator>> to extract the 1st word of the line:
#include <sstream>
...
string line;
getline(cin, line);
istringstream(line) >> username;
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am having a number of problems in my program that all have to do with input.
The first thing in the program I ask the user to input is their name which I do so with this
cout << "Please tell me your name." << endl;
getline(cin, user_name);
cout << "Hello " << user_name << " and welcome to Fantasy Battle!" << endl;
where user_name is declared as a string variable elsewhere. This part seems to have no problems as the following message displays to the screen correctly
The next input from the user comes from this code
{
cout << "Hello, what would you like to do?" << endl;
cout << "1. Play" << endl << "2. Exit" << endl;
cout << "Please enter the number corresponding to your choice from the list
above." << endl;
for(;;)
{
if(cin >> menuChoice)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(10000, '\n');
}
if(menuChoice == 1 || menuChoice == 2)
break;
else
{
cout << "You did not enter a valid menu option. Please try
again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
else
{
cout << "You did not enter a valid menu option. Please try again."
<< endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
if(menuChoice == 2)
{
return 2;
}
else
{
//setup a fight code further down
}
One the first run through if I enter 2 it will exit the program successfully from main or if enter 1 it will run through the fight function. However, if I go through 1 fight and get back the program asking me to either enter 1 or 2 to play or exit, I can enter 2 infinite times and it will not exit the program. I am not sure what it causing this.
for(;;)
{
game = menu();
if(game == 2)
{
break;
}
else
{
fight();
}
}
return 0;
The code inside the menu() function of my program is as follows and is where the rest of the input for my program is contained. I am using getline(cin, fighterName) to get a string from the user to use as a name for each character they want to create
The problem I am having is that it starts to just save the name of characters as empty without asking.
cout << "How many fighters should be on Team 1?" << endl;
//Input Validation
for(;;)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(100000, '\n');
}
if(cin >> team1Size)
{
if(team1Size <= 0)
{
cout << "The team must be a size of at least 1 fighter. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
{
break;
}
}
else
{
cout << "You did not enter a valid number. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
cout << "How many fighters should be on Team 2?" << endl;
//Input Validation
for(;;)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(100000, '\n');
}
if(cin >> team2Size)
{
if(team2Size <= 0)
{
cout << "The team must be a size of at least 1 fighter. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
{
break;
}
}
else
{
cout << "You did not enter a valid number. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
//Set up team 1
cout << "Begin setup for team 1:" << endl << endl;
for(int i = 0; i < team1Size; i++)
{
cout << "Which character type should fighter " << i+1 << " be?" << endl;
cout << "1. Barbarian" << endl;
cout << "2. BlueMen" << endl;
cout << "3. Vampire" << endl;
cout << "4. Medusa" << endl;
cout << "5. Harry Potter" << endl;
cout << "Please enter the number corresponding to your choice from the list above." << endl;
for(;;)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(100000, '\n');
}
if(cin >> fighterType)
{
if(fighterType < 1 || fighterType > 5)
{
cout << "You did not enter a valid choice. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
break;
}
else
{
cout << "You did not enter a valid choice. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
//Now that we have the desired type of the fighter we must add a fighter of the correct type to the linked list
//representing team 1. We will do so by calling the add function of the linked list
cout << "Please enter the name of this fighter." << endl;
getline(cin, fighterName);
if(fighterType == 1)
{
team1.addBack("Barbarian", fighterName);
}
else if(fighterType == 2)
{
team1.addBack("BlueMen", fighterName);
}
else if(fighterType == 3)
{
team1.addBack("Vampire", fighterName);
}
else if(fighterType == 4)
{
team1.addBack("Medusa", fighterName);
}
else
{
team1.addBack("HarryPotter", fighterName);
}
}
cout << "Team 1 has been created!" << endl << endl;
//Set up team 2
cout << "Begin setup for team 2:" << endl << endl;
for(int i = 0; i < team2Size; i++)
{
cout << "Which character type should fighter " << i+1 << " be?" << endl;
cout << "1. Barbarian" << endl;
cout << "2. BlueMen" << endl;
cout << "3. Vampire" << endl;
cout << "4. Medusa" << endl;
cout << "5. Harry Potter" << endl;
cout << "Please enter the number corresponding to your choice from the list above." << endl;
for(;;)
{
if(cin.get() == '.')
{
cin.clear();
cin.ignore(100000, '\n');
}
if(cin >> fighterType)
{
if(fighterType < 1 || fighterType > 5)
{
cout << "You did not enter a valid choice. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
break;
}
else
{
cout << "You did not enter a valid choice. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
//Now that we have the desired type of the fighter we must add a fighter of the correct type to the linked list
//representing team 2. We will do so by calling the add function of the linked list
cout << "Please enter the name of this fighter." << endl;
getline(cin, fighterName);
if(fighterType == 1)
{
team2.addBack("Barbarian", fighterName);
}
else if(fighterType == 2)
{
team2.addBack("BlueMen", fighterName);
}
else if(fighterType == 3)
{
team2.addBack("Vampire", fighterName);
}
else if(fighterType == 4)
{
team2.addBack("Medusa", fighterName);
}
else
{
team2.addBack("HarryPotter", fighterName);
}
}
cout << "Team 2 has been created!" << endl << endl;
cout << "Let the fight begin!" << endl << endl;
return 0;
}
The final piece of input from my code is the following which simply asks the user to enter a character either y or n and then executes a function if y is entered.
cout << "Would you like to see the contents of the loserPile?" << endl;
cout << "Please enter y for yes or n for no" << endl;
for(;;)
{
if(cin >> displayLosers)
{
if(displayLosers != 'y' && displayLosers != 'n')
{
cout << "You did not enter either y or n. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
else
break;
}
else
{
cout << "You did not enter either y or n. Please try again." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
if(displayLosers == 'y')
{
losers.displayPile();
}
If someone could point out where I am making the error in obtaining user input I would appreciate it as I am running out of things to try that I know of.
You are creating a lot of problems by adding if(cin.get() == '.')
The >> operator will convert the input string "1." to 1, and if you call ignore(...,'\n') the . and any other characters before \n will be ignored. Test for if(cin >> number){...} is also not necessary. You can initialize the value to -1 to indicate an error:
int menuChoice;
for(;;)
{
menuChoice = -1;
cin >> menuChoice;
cout << menuChoice;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if(menuChoice == 1 || menuChoice == 2)
{
cout << menuChoice << "\n";
break;
}
cout << "You did not enter a valid menu option. Please try again." << endl;
}
Just make sure you are using the right input. For Yes or No option the input should be char:
cout << "enter y or n\n";
for(;;)
{
char val;
cin >> val;
if(val != 'y' && val != 'n')
{
cout << "You did not enter either y or n. Please try again." << endl;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
else
break;
}
when press "1" to start the game a error message comes up first instead of playing the game and then I have to enter "1" 3 times before the game starts and also the quit game option only works when you select "2" first if its not selected first it just comes up as a error message I cant see why it does this can anyone help me please ?
#include "Questions.h"
#include <iostream>
using namespace std;
const int MAXITEMS = 10;
int main ()
{
string question[MAXITEMS] = {"How man cards in a suit",
"How_many_suits_are_there_in_a_standard_pack_of_card",
"How_many_kings_are_in_a_standard_pack_of_cards"};
string answers[MAXITEMS] = {"4", "5", "6"};
int userInput = 0;
int tries = 0;
bool isGameOver = false;
cout << "select 1 to start game" << endl; //gives option to start and quit game
cout << "select 2 to quit game" << endl;
cin >> userInput;
if (userInput == 2)
{
isGameOver = true;
return 0;
};
// when game starts gives option to select question and shows all questions
do
{
if (userInput != 1||2)
{
cout << " Your input is not valid! please try again:" << endl;
// try switch cases for the different outcomes
cout << "select 1 to start game" << endl;
cout << "select 2 to quit game" << endl;
cin >> userInput;
while (!(cin >> userInput))
{
cin.clear(); // clear the error flags
cin.ignore(INT_MAX, '\n'); // discard the row
cout << "Your input is not valid! please try again: ";
cout << "select 1 to start game" << endl;
cout << "select 2 to quit game" << endl;
}
cout << userInput << endl;
}
// reprisent all characters as number to stop while roblem
if(userInput == 1)
{
do
{
cout << "select question" << endl;
for(int i = 0; i != MAXITEMS; i++)
{
cout << i << " " << question[i] << endl;
}
int selectQestion;
cin >> selectQestion;
if(selectQestion == 0||1||2 && tries != 2)
{
cout << "Enter your answer" << endl;
string userAnswer;
cin >> userAnswer;
while (!(cin >> userAnswer))
{
cin.clear(); // clear the error flags
cin.ignore(INT_MAX, '\n');
// discard the row
cout << "Your input is not valid!
please try again: ";
}
if (userAnswer == answers[0])
{
cout << "Correct answer" << endl;
}
else{
cout << "incorrect try again" << endl;
tries++;
cin >> userAnswer;
if (userAnswer == answers[0])
{
cout << "Correct answer" << endl;
}
else
cout << "Incorrect" << endl;
}
}
if (selectQestion == 0 ||1 ||2 && tries == 2)
{
cout << "you can no longer answer this question" << endl;
cout << "try another question" << endl;
}
}
while(userInput == 1);
}
}
while(isGameOver == false);
}
// add stuct or class to handle questions,
if (userInput != 1||2) doesn't do what you think. With the proper paretheses inserted, it is
if ((userInput != 1) || 2)
and 2 is nonzero, hence the condition is always true.
You want
if (userInput != 1 && userInput != 2)
The problem lies here:
if (UserInput!=1||2)
In this line, there are two conditions:
UserInput!=1 , 2
Here , whether user input is 1/2, the second condition 2 is always evaluated as true, which runs the if block
So change it to
if (UserInput!=1 && UserInput!=2)
i need to prevent the junk left in the buffer as entering a value for a switch case menu from being used in a function called by the menu where their is user input.
menu code
void menu()
{
bool done = false;
string input;
while(!done)
{
cout << "Welcome to the DVD database." << endl;
cout << "1. Add A DVD" << endl;
cout << "2. Delete a DVD." << endl;
cout << "3. Edit a DVD." << endl;
cout << "4. List By Category." << endl;
cout << "5. Retrieve by a DVD by Title." << endl;
cout << "6. Display collection by year" << endl;
cout << "7. Display collection by title" << endl;
cout << "-999. Exit program" << endl;
cout << "Please choose an option by entering the corresponding number" << endl;
cin >> input;
int value = atoi(input.c_str());
switch(value)
{
case 1:addDVD(); break;
case 2:deleteDVD(); break;
// case 3:editDVD(); break;
case 4:listByCategory();break;
case 6:displayByYear();break;
case 7:displayByTitle();break;
case -999: writeToFile(); exit(0); break;
default : cout <<"Invalid entry"<< endl; break;
}
}
}
void retrieveByTitle()
{
string search;
int size = database.size();
int index = 0;
bool found = false;
cin.ignore();
cout << "Please enter the title of the DVD you would like to retrieve: " << endl;
getline(cin,search);
cout << search;
while(!found && index<size)
{
if(database.at(index)->getTitle().compare(search)==0)
{
cout << database.at(index)->toString();
break;
}
}
cout << endl;
}
if 5 is entered in the menu, the program skips the user input in the method
This code works, but it has the same problem you describe if you eliminate the 'cin.ignore()', which removes the extra delimiters ignored by the cin >> operator:
#include <iostream>
#include <climits>
using namespace std;
int main() {
string a, b;
while (true) {
cout << "write 'x' to exit: " << endl;
cin >> a;
if (a == "x") {
break;
}
cout << "read '" << a << "'" << endl;
cout << "now write a line: " << endl;
cin.clear(); // clears cin status
cin.ignore(INT_MAX); // clears existing, unprocessed input
getline(cin, a);
cout << "read '" << a << "'" << endl;
}
return 0;
}
When dealing with interactive user input you should use std::getline()
The std::cin is flushed to the application every time you hit <enter>. So this is the logical junks you should read data from the user in.
std::string answer;
std::cout << "Question:\n";
std::getline(std::cin, answer);
This gets you everything the user provided in response to the previous question.
Once you have the input you should get the value you think is on the input. Once you have this you should check if there is any other junk on the input (if there is then abort and re-try) otherwise validate the data you expected.
If you were expected an integer;
std::stringstream linestream(answer);
int value;
std::string junk;
if ((answer >> value)) && (!(answer >> junk)))
{
// If you got data
// and there was no junk on the line you are now good to go
}
In your specific example there is already a simple way to do this:
std::getline(std::cin, input);
int value = boost::lexical_cast<int>(input); // throws an exception if there is not
// an int on the input (with no junk)