How do I validate input without exiting my do while loop? - c++

I'm working on a program that prompts the user to select from 3 different options by inputing an integer from 1-3 (4 to quit). I need to write a code that validates that the input is an integer, and reprompts them if it is not an integer. Here's the basic idea of my code (it is too long to post in entirety).
do
{
cout << "Menu: Please select one of the following options:" << endl;
cout << " 1 - Drop a single chip into one slot." << endl;
cout << " 2 - Drop multiple chips into one slot." << endl;
cout << " 3 - Drop 5 chips into each slot." << endl;
cout << " 4 - Quit the program." << endl;
cout << "Enter your selection now: ";
cin >> first_input;
}while (first_input!=4)
I then have multiple if statements that execute expressions based on which option the user chooses. I also prompt them to enter other integer values later in the code.
How do I send the user back to the menu, if the user inputs fails to input an integer and instead inputs characters? Constraints: Cannot use continue or break
Thanks in advance.

If you want to go back to the start in case of non-integer input, perhaps something like this would work?
// Insert after "cin >> first_input;"
if (cin.fail()) {
// Handle non-int value.
// Clear error flag.
cin.clear();
// Empty buffer up to next newline.
cin.ignore(numeric_limits<streamsize>::max(), '\n');
// Complain & restart.
cout << "Invalid input. Please try again." << endl;
continue;
}
What this does is clear the error flag, purge the buffer, and go back to the start. cin.ignore() doesn't explicitly need to be passed std::numeric_limits<std::streamsize>::max() as its first parameter; however, in case of error, I prefer to do so to make sure that the erroneous input is gone. Note that std::numeric_limits is defined in the standard header <limits>, and requires its inclusion.

You are looking for the continue keyword.

do
{
cout << "Menu: Please select one of the following options:" << endl;
cout << " 1 - Drop a single chip into one slot." << endl;
cout << " 2 - Drop multiple chips into one slot." << endl;
cout << " 3 - Drop 5 chips into each slot." << endl;
cout << " 4 - Quit the program." << endl;
cout << "Enter your selection now: ";
cin >> first_input;
//lets say if user enters value out of range. then want to show menu again.
if(first_input > 4) {
cout << "Invalid input "<<endl;
continue;
}
// you can do other stuff here.
// ...
}while (first_input!=4)

You can try using goto label.
do{
label:
// your code
if(check) goto label;
}while(check);

Related

Best substitute for goto in C++ as beginner for use in text-based RPG

I am very new to C++ and have decided to start with a basic text based RPG. I have been using this site as a reference; https://levelskip.com/classic/Make-a-Text-Based-Game#gid=ci026bcb5e50052568&pid=make-a-text-based-game-MTc0NDU2NjE2MjQ1MDc3MzUy
system("cls");
int choiceOne_Path;
cout << "# What would you like to do?" << endl;
cout << "\t >> Enter '1' to follow the Chief?" << endl;
cout << "\t >> Enter '2' to find your own path?" << endl;
retry:
cout << "\nEnter your choice: ";
cin >> choiceOne_Path;
if(choiceOne_Path == 1)
{
cout << "\n!!!----------------------Chapter One: Escape----------------------!!!" << endl;
cout << "\nYou: Where are we going?" << endl;
cout << "Chief: Soon you will know. Just follow me." << endl;
cout << "# You run behind the chief." << endl;
}
else if(choiceOne_Path == 2)
{
cout << "\n!!!----------------------Chapter One: Escape----------------------!!!" << endl;
cout << "\nYou: I am going to find a way out!" << endl;
cout << "Chief: You are insane. You will get killed out there." << endl;
cout << "You: I have my secrets and I know my way out." << endl;
cout << "# You jump over the nearby broken fence" << endl;
cout << "# and run off towards the City Wall." << endl;
}
else
{
cout << "You are doing it wrong, warrior! Press either '1' or '2', nothing else!" << endl;
goto retry;
}
cout << "\n----------------------Press any key to continue----------------------" << endl;
_getch();
This is the code that the site shows as a reference but I have had some issues with it. Primarily with the "goto" command only working for incorrectly inputted integers. If you enter a letter character there, it makes an infinite loop instead.
During my search for a solution to the problem I found a great deal of animus towards the "goto" function. Modern code has essentially refuted it's use as I understand it. So at this point I am looking for a different function that can perform that task of redoing the cin function upon inputting an unusable character.
I am entirely willing to use a completely different structure or system if there isn't a natural replacement for that command in this context.
Best substitute for goto
retry:
// accept input
if (/* input predicate */)
{
// ...
}
else
{
// ...
goto retry;
}
That's what we in the trade call a "loop". Any flavor of loop structure is fine for this example, but this is a rare case where do-while is nice. A direct transformation:
do
{
// accept input
if (/* input predicate */)
{
// ...
break;
}
else
{
// ...
}
} while(true);

program ignores everything after cin.get() and skips back to the menu

I'm stuck with this problem and I've tried everything I can think of. My program is a music database with a menu for selecting options.
I have a function for reading in data to add a new song to the database. My cin.get() statements seem to work, and it's echoing back the right information. But as soon as I get to the last cin.get(), it just skips straight back to the menu. I put in some dummy cout statements after this chunk of code and they never execute.
Here the function I'm having trouble with. I can post the rest of the program if necessary. I would really appreciate help with this. I'm betting this is something really simple, I'm just too much of a beginner to see what the problem is.
Thanks in advance for any help!
void inputNew(songType songs[], int &numSongs)
{
char songName[100];
char artist[100];
int min;
int sec;
char album[100];
clearScreen();
cout << "Enter the name of the song: ";
cin.get(songName, 100, '\n');
cin.ignore(100, '\n');
cout << "You entered: " << songName << endl;
cout << "Enter the name of the artist: ";
cin.get(artist, 100, '\n');
cin.ignore(100, '\n');
cout << "You entered " << artist << endl;
cout << "Enter the minutes: ";
cin >> min;
cout << "You entered " << min << "minutes" << endl;
cout << "Enter the seconds: ";
cin >> sec;
cin.ignore(100, '\n');
cout << "You entered " << sec << "seconds" << endl;
cout << "Enter the album name: ";
cin.get(album, 100, '\n');
cin.ignore(100, '\n');
cout << "testing" << endl;
In the repl you posted in the comments main has a while loop.
while (answer != 'q')
{
displayMenu(songs, answer, numSongs);
processRequest(songs, answer, numSongs); // Internally calls inputNew
}
displayMenu clears the screen and writes the menu. If you don't break in some way the execution, you will not be able to see the text that processRequest wrote. You need to add an std::cin.get() after all your outputs (like at the end of processRequest). If you want you can add a message like Press enter to continue... right before std::cin.get().

My program keeps looping in the first do...while loop even when condition isn't met

I started learning C++ 3 days ago, and after some experimenting with loops and vector I decided to do something actually useful with it: an Account Manager.
The point is, I'm using a do...while loop, for the 1rst action in my program (which is adding a new website), however past this point, the loop won't end even when the condition isn't met any more.
I tried to debug it for a good 30 minutes and found nothing odd.
Here's the code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
/*Introduction
//Ask whether the user(me) wants to open an account already created, add a new one, or remove an existing one
To show credentials a master password is required
I need something that can:
1. Find the place where credentials are supposed to be filled
2. Enter them efficiently
3. Bonus : Submit the data on the website and automatically connect*/
int userAction; // Variable de sélection de la première action
string siteNameVar("site"), urlVar("url"), userNameVar("username"), passwordVar("pass") ;
char sureVerification;
vector<string> siteName(0); // Vectors containing respectively : "The sites names"
vector<string> url(0); // Vectors containing respectively : "The sites urls"
vector<string> userName(0); // Vectors containing respectively : "The usernames"
vector<string> password(0); // Vectors containing respectively : "The passwords"
cout << "What will you do?" << endl;
cout << "1. Add a website account" << endl
<< "2. Connect to an existing account" << endl
<< "3. Delete an account"<< endl;
cin >> userAction; // This is where the user enter his choice
switch (userAction){
case 1: // Add a new element in the vectors
do{
//Site Name
do{
cout << "Enter the site's name (or how you want to call it)" << endl;
cin >> siteNameVar;
cout << "Are you sure? 1 = yes | Anything else = no" << endl;
cin >> sureVerification;
}
while (sureVerification != 1);
//Site's Url
do{
cout << "Enter the site's login page url" << endl;
cin >> urlVar;
cout << "Are you sure? 1 = yes | Anything else = no" << endl;
cin >> sureVerification;
}
while(sureVerification != 1);
url.push_back(urlVar);
// Username
do{
cout << "Enter your account's username" << endl;
cin >> userNameVar;
cout << "Are you sure? 1 = yes | Anything else = no" << endl;
cin >> sureVerification;
}
while(sureVerification != 1);
userName.push_back(userNameVar);
// Password
do{
cout << "Enter your account's password" << endl;
cin >> passwordVar;
cout << "Are you sure? 1 = yes | Anything else = no" << endl;
cin >> sureVerification;
}
while(sureVerification != 1);
password.push_back(passwordVar);
//Display Everything
cout << "So the site's name is :" << siteName.back() << endl
<< "The login page url is :" << url.back() << endl
<< "Your account's username is :" << userName.back() << endl
<< "And your password is :" << password.back() << endl;
//Last verification
cout << "Is everything alright? 1 = yes | Anything else = no" << endl;
cin >> sureVerification;
}
while(sureVerification != 1);
cin.get();
break;
case 2: // Connect to an existing account
cout << "display map element names" << endl;
break;
case 3: // Delete an account
cout << "display map element names2" <<endl;
break;
} // End of the choice sequence
cin.get();
return 0;
}
You should try cleaning the input buffer. Use cin.clear() and cin.ignore() before reading the user's input (eg. before cin >> sureVerification)
(Posted on behalf of the question author).
Wow, after comparing an earlier version of my code to the code I posted, and substituting a piece of the old code to the new one (which "oddly" worked), I realized that the problem was all due to the fact that the value-type of sureVerification (read code to understand) was char and in the verification expression I had wrote the 1 (which was equivalent of "Yes" as an int.
Problem solved!

C++ reset cin and cout

Ok so I have 3 functions that all represent a question that I need to answer. My first question is working with cin and cout, and is broken into parts. The problem is that after one part finishes, another part automatically takes the remainder of the input in the first part rather than asking for a new input.
My problems lay in
//part B
char state[30];
cout << "Enter a sentence: " << endl;
cin.read(state, 15);
cout << "The sentence entered was:\n";
cout.write(state, cin.gcount());
cout << endl;
and
//part E
char charArray[12]; //creates an array of 12
cout << "Enter some characters: " << endl;
cin.getline(charArray, 12, 'y');
cout << "Your characters are: " << charArray << endl;
Where whatever I enter in part b gets used in part e. I have tried using clear, ignore, and flush but to no avail. Also, the original input gets used in my other functions, as well.
My main is set up like this:
int main()
{
question1();
question2();
question3();
}
How am I able to enter a fresh input to use in each part and each function?

C++ how to stop from crashing if entering letters

I have a task to make a program that will calculate two numbers put into it.
And also show the calculation between every number.
And if I input a letter not a number the program crashes, this is an more advanced task that I dont need to do but I really want to know how to do this. So that is my question, how do I make the program give me a warning that not to use letters and still give u ability to input numbers if you enter a letter, instead of crashing.
This is how my code looks so far
Blockquote
float nmr1, nmr2;
cout << "Write two numbers.\n";
cin >> nmr1;
cin >> nmr2;
cout << "\n";
cout << nmr1 << " + " << nmr2 << " = " << nmr1 + nmr2 << endl;
cout << nmr1 << " - " << nmr2 << " = " << nmr1 - nmr2 << endl;
cout << nmr1 << " * " << nmr2 << " = " << nmr1 * nmr2 << endl;
cout << nmr1 << " / " << nmr2 << " = " << nmr1 / nmr2 << endl;
cin.get();
cin.get();
return 0;
maybe there are easier things to write but I'm a beginner, and I would use the search tool but I don't know what to search.
cin >> var_of_type_float will return false if the input fails. So simply use that in a conditional expression, something like:
if (cin >> nmr1) { // all ok
If you want to check the input, usual way is to read a string, check if there are non valid character, then parse it into a number (tedious task in C++ with real numbers) and store in a float, finally, perform operations with those floats.
If you are not working with text input yet, I recommend you to wait to implement this feature, as it could be complex for a beginner in programming
To check if a bad input was received via cin you use the following condition:
if(!cin){
// bad input was received, don't use cin again.
}
What really crashes is the divide-by-zero operation.
If invalid number is entered, nmr1 and nmr2 will be 0
and nmr1/nmr2 will crash. You must check for (nmr2 != 0) before attempting to divide.