C++ How to enter user values without breaking program - c++

I am trying to get an integer from the user but if they type "ckefkfek" it will cause the program to spam and break. I also want them to enter a float but I get the same problem and no clue how to check for this.
int option = 0;
while (option != 3)
{
cout << "Enter 1, 2, or 3: ";
cin >> option;
switch (option)
{
case 1:
cout << "Enter a float: ";
float myfloat;
cin >> myfloat;
myFunc(myfloat); // must be a float for this function to work.
break;
case 2:
// do stuff
break;
case 3:
// do stuff
break;
default:
cout << endl << "Not a valid option." << endl;
break;
}
}
How can I do this without constant errors? Thank you!

bool input_ok = false;
while (!input_ok)
{
cout << "Enter 1, 2, or 3: ";
if (cin >> option)
{
input_ok = true;
...
}
else
{
cout << "Stop being silly\n";
std::string dummy;
if (cin >> dummy)
cin.clear();
else
throw std::runtime_error("OK, I'm not playing any more");
}
}
Basically if the input can fail, you need to test whether it failed. You test that by checking the state of the stream after reading from it, with cin >> option; if (cin) ..., or by combining the read and test like this: if (cin >> option) ...
If input fails, read whatever couldn't be parsed as an integer and discard it, and try again.

Related

reuses "rechnung()" even though it shouldn't

#include <iostream>
#include "funktionen.h"
using namespace std;
int rechnung()
{
cout << "Please choose the operator you want to calculate with" << endl;
int eingabe1;
int eingabe2;
int eingabe;
int dummy;
char zeichen;
char again;
cin >> zeichen;
cout << endl << "1. Eingabe: ";
cin >> eingabe1;
cout << endl << "2. Eingabe: ";
cin >> eingabe2;
switch (zeichen)
{
case '+':
eingabe=eingabe1 + eingabe2;
break;
case '-':
eingabe=eingabe1 - eingabe2;
break;
case '*':
eingabe=eingabe1 * eingabe2;
break;
case '/':
eingabe=eingabe1 / eingabe2;
break;
}
cout << endl << "Das Ergebnis ist | " << eingabe << " | " << endl << endl;
cout << "Wanna calculate again? ";
cin >> again;
while(again=='Y')
{
rechnung();
}
return 0;
}
So this is my code in an implementation file. My problem is, that the main program always loops the whole "rechnung()" function even though I don't type "Y" into the console once it asks for it. In the beginning, when I type something else than "Y", then the console closes (as it shall) but if I do a calculation, type "Y", do another calculation and type "k" for example, it also starts from the beginning of "rechnung()". Why does it do so? I mean I told him that he shall only recall the "rechnung()" if the character input is "Y".
Consider this maybe simpler example:
void foo() {}
void bar() {
char again;
// ... do something
std::cin >> again;
while(again=='Y') {
foo();
}
}
Inside the loop the value of again never changes, so there is an infinite loop. However, your code goes one step further by calling the function recursively. Strongly simplified you have:
void bar() {
// .. do something
while (true) {
bar();
}
}
ie bar is calling itself again and again and never returns. You put the loop at the wrong place. You could write it like this
void bar() {
char again = 'Y';
while (again == 'Y') {
// .. do something
std::cout << "repeat?";
std::cin >> again;
}
}

String input in a function within a switch-case statement results in infinite loop and bypassing of input? [duplicate]

This question already has answers here:
Why would we call cin.clear() and cin.ignore() after reading input?
(4 answers)
Closed 5 years ago.
Novice trying to self teach himself C++ here.
Here is the code for reference:
#include <iostream>
void function1(int);
void function2(int);
void function3(int);
using namespace std;
int main() {
int input = 0;
while (input != 4){
cout << "Prompt" << endl;
cin >> input;
switch(input) {
case 1:
function1(input);
break;
case 2:
function2(input);
break;
case 3:
function3(input);
break;
case 4:
cout << "Program terminated." << endl;
return 0;
break;
default:
cout << "Invalid input." << endl;
input = 4; // Exits the while-loop.
break;
}
}
}
void function1(int a) {
int prompt;
cout << "Prompt again" << endl;
cin >> prompt;
if (!cin){
cout << "Input is not a number." << endl;
return;
}
}
void function2(int a) {
}
void function3(int a) {
}
What I'm trying to do is make a function1 that detects if a specific input was a string or a char instead of an integer, and then say that it is not a number, then go back to the switch case statements. Once it detects this though, the statements in the while loop go on forever and completely bypass the cin prompts! I understand from reading other people's questions that the infinite looping might have something to do with using 'int' in a header and inputting a string when an integral is expected, but I don't understand why the code doesn't stop when the cin is prompted or how to bypass it. Any help?
if (!cin){
cout << "Input is not a number." << endl;
return;
}
When cin<< reads a bad input, its flags are set to an error state. The error state needs to be cleared by resetting the flags to zero, which is done using cin.clear(). Change your if-statement to include the cin.clear() statement:
if (!cin){
cout << "Input is not a number." << endl;
cin.clear(); // <-- Add this line
return;
}
When you enter invalid input for cin <<, the error flags of cin<< are set to 1 (true). That is why we use cin.clear(); so that the error flags are reset to zero, and cin<< can accept new input.

Functions to check if the user's input is correct not working

I have created some C++ code that is supposed to check to see if a user's input is correct but it isn't quite working how I want it to. Whenever you type an integer first, and then a couple of characters after it, the terminal spams would you like to try again y/n a couple of times. I have tried to limit the amount of times it can output this, but nothing has worked.
#include <iostream>
#include <limits>
using namespace std;
int again()
{
char yorn = 'q';
cout << "\n Would you like to run this program again? y/n: ";
cin >> yorn;
if (cin.fail()) {
int dof1 = 1; // dof1 stands for don't overflow 1
for (int i = 0; i < dof1; i++) {
cout << "ERROR -- You did not enter a valid symbol";
// get rid of failure state
cin.clear();
// discard 'bad' character(s)
cin.ignore(numeric_limits<streamsize>::max(), '\n');
bool check = again();
if (check == true) {
check = false;
return again();
}
else
return 0;
}
}
switch (yorn) {
case 'y':
return true;
break;
case 'n':
return false;
break;
default:
return again();
break;
}
}
int main()
{
int choice = 0;
cout << "\nWelcome to the Weight Tracker! Type 000 at any time to exit\n"
<< "Choose the option you would like to use below \n"
<< "1) \n"
<< "2) \n"
<< "3) \n"
<< "Option selected: ";
cin >> choice;
if (cin.fail()) {
int dof2 = 1; // dof2 stands for don't overflow 2
for (int i = 0; i < dof2; i++) {
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// discard 'bad' character(s)
cin.ignore(numeric_limits<streamsize>::max(), '\n');
bool check = again();
if (check == true) {
check = false;
return main();
}
else
return 0;
}
}
switch (choice) {
case 1:
cout << " use later";
break;
case 2:
cout << " use later";
break;
case 3:
cout << " use later";
break;
default:
cout << "ERROR -- Input invalid \n";
bool check = again();
if (check == true) {
check = false;
return main();
}
else
return 0;
break;
}
return 0;
}
You are missing one cin.ingnore
default:
cout << "ERROR -- Input invalid \n";
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // ADD this line
bool check = again();
To be honest. This code is mess. Please remove recursion from it.

How to make an exit in switch case implementation with user prompt?

I've a basic computing program, in it I want that when a user wants to just quit the program in his very first input without making any calculation, the program just exits. But rather here if the user enters q for quit/exit in his first input the programs runs into an infinite loop. Is there any way to provide user with some single exit key which when entered anytime(by the user) during runtime just quits the program. The innermost while loop works fine unless the outermost loop stops working.
#include "std_lib_facilities.h"
int main() {
double x = 0, y = 0, result = 0;
string operation = " ";
char op = ' ';
cout << "\nInput (e.g. -> 5*6)\nPress q to quit.\n";
while(1) {
cin >> x >> op >> y;
switch(op) {
case '+':
result = x + y;
operation = "sum";
break;
//Other switch cases
case 'q':
exit(1);
default:
cout << "Invalid input.";
break;
}
cout << "The " << operation << " of " << x << " and " << y << " is "
<< result << ".\n\n"
<< "If you have another input, press any character to continue..\n"
<< "Else press q to quit.\n";
// exit or continue program loop
while(cin >> op) {
if(op=='q' || op=='Q')
exit(1);
else
cout << "Provide next set of inputs.\n";
break;
}
}
}
If the user enter q on the first try then the stream will try to read this value to x which is a double which will fail and the state of the stream will be set to fail, after that no other I/O operation will be successfully performed and the loop will run infinitely.
You could probably check for the state of the stream just before you ask the user to continue or quit and clear the stream state if the previous operation was failed:
if(cin.fail())//check if the previous read operation failed
cin.clear();//clear the stream state,so the next cin will read what is in the buffer
while(cin >> op)
...//your other code
Try this:
boolean quit = FALSE;
while (!quit)
{
...
switch (op)
{
case 'q':
quit = TRUE;
break;
}
}
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
char ch;
while(true)
{
cout<<"l.print l "<<endl<<"c.print c "<<endl<<"q. exit"<<endl;
cout<<"enter choice"<<endl;
cin>>ch;
switch(ch)
{
case 'l':
cout<<"You have typed l "<<endl;
break;
case 'c':
cout<<"You have typed c"<<endl;
break;
case 'q':
cout<<"Exit ..." <<endl;
exit(0);
default:
cout<<"Wrong choice "<<endl;
}
}
return 0;
}

while loop - nothing happens after first input

int option;
int invalidOption2 = 0;
while(invalidOption2 == 0){
try{
cin>>option;
if(!cin){
error("invalid input");
}
if(option<1 || option>2){
error("invalid input");
}
if(option==1) {
invalidOption2 = 1;
cout<<"option 1 was selected"<<endl;
}
else if(option==2) {
invalidOption2 = 1;
cout<<"option 2 was selected"<<endl;
}
}
catch(runtime_error& e) {
cerr <<"Please enter a valid option" << endl;
}
}
When using the above code, for the first value I input it will move on to the next line and wait for another input, instead of displaying either the option messages or the error message. However when I enter a second value it works as normal.
for example if I entered
a (nothing happens here, so I need to enter another value)
1
"you have selected option 1"
would be displayed and no error message for the original invalid input.
I would like to know how to get the result below instead.
a
"Please select a valid option"
1
"you have selected option 1"
any help would be appreciated
You won't get to the "Please enter a valid option" unless an
exception is thrown. You don't show error, but if it doesn't
throw an exception, you'll never get to the catch block.
Also, cin >> option almost certainly leaves a new line in the
buffer, which may cause later problems, and whien you enter an
alpha, if option is type int, cin will enter an error
state, which needs to be cleared (and the erronous input
removed). So in the error case (!cin), you need to call
cin.clear(), and in all cases, you probably want to call
cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n'
).
An alternative solution, which avoids most of these problems, is
to read complete lines (using std::getline( std::cin, line )),
and then use std::istringstream to parse the line. This will
leave std::cin in a good state, and ready to input the next
line.
Option is likely of integer type, so cin can't read 'a' into it, so it is ignored.
Is this your case?
You could modify it like this:
char option;
while(invalidOption2 == 0){
try{
cin>>option;
if(!cin){
error("invalid input");
}
if(option<'1' || option>'2'){
error("invalid input");
}
if(option=='1') {
invalidOption2 = 1;
cout<<"option 1 was selected"<<endl;
}
else if(option=='2') {
invalidOption2 = 1;
cout<<"option 2 was selected"<<endl;
}
}
catch(runtime_error& e) {
cerr <<"Please enter a valid option" << endl;
}
}
This should work how you expect it to.
However, construction like this:
char option;
while (cin >> option) {
if ((option == '1') || (option == '2')) {
break;
}
else {
cout << "Please enter 1 or 2." << endl;
}
}
cout << "option " << option " << " was selected" << endl;
Is probably better ^_^
I think this looks a better code (at least for the eyes):
int option;
int invalidOption2 = 0;
while(invalidOption2 == 0)
{
try
{
cin>>option;
switch(option)
{
case 1 :
invalidOption2 = 1;
cout<<"option 1 was selected"<<endl;
break;
case 2 :
invalidOption2 = 1;
cout<<"option 2 was selected"<<endl;
break;
default :
error("invalid input");
}
catch(runtime_error& e)
{
cerr <<"Please enter a valid option" << endl;
}
}
If you still think you have problems with int and char with cin then better use :
option = getchar();
I think calling cin twice may be the issue here, but I'm not certain. Something like this should work well too:
char option[80]; // 80 is the standard terminal line length
bool loop = 1;
while(loop)
{
cin >> option;
if (option[1]=='\n') // testing if string is length 1
{
cout << "Please select a valid input\n";
continue; // if not, display error and try again
};
switch(option[0])
{
case '1': loop=0; break; // add whatever before break
case '2': loop=0; break;
default: cout << "please select a valid input\n"; break;
};
};
cout << "Option "<< option << "was selected\n";
I didn't compile this, but it should be okay.