Error checking two separate inputs - c++

I'm trying to check two separate inputs if they are integers or not. I'm able to error check one input but I'm not quite sure how to check two separate ones if I'm using the 'get' function and both inputs are from the 'cin' stream. Using c++.
My code for checking one integer is displayed below.
#include <iostream>
using namespace std;
int main() {
int input;
cout << "Enter an integer: ";
cin >> input;
char next;
int x=0;
int done = 0;
while (!done){
next = cin.get();
if (next == ' ' || next == '\n'){
cout << "The Integer that you have entered is: " << input << "\n";
done = 1;
}
else if (next == '.'){
cerr << "Error: Invalid Input. Not an Integer." << "\n";
done = 1;
}
else{
cerr << "Error: Invalid Input. Not a number." << "\n";
done = 1;
}
}
return 0;
}

Well you could use >> into an int all the way through, drop all that get() stuff and character handling, and check cin.fail(). For example (I'll leave working this into your program and repeating it in a loop as an exercise for you):
int x;
cin >> x;
if (cin.fail())
cout << "Not a valid integer." << endl;
You can handle all subsequent input in exactly the same way. There's no reason to only limit operator >> to the first input.

Related

Trying to validate input in C++

The idea behind this code in c++ is to calculate the sum of all the entered numbers. When the user enters 0, the program should stop. This part of the code is working as I intended, but I'd like to include a variant which recognizes that a character different than a float number has been entered, ignore it in the calculation and allow the user to continue entering float numbers. At the moment, entering anything else but a float number stops the program.
I know there's a "if (!(cin >> numb))" condition, I've tried parsing it in different places in the code, but I can't figure out how to force the program to ignore these invalid inputs. I would be very grateful for any help.
#include <iostream>
#include <stdlib.h>
using namespace std;
float numb; float sum=0;
int main()
{
cout << "This app calculates the sum of all entered numbers." << endl;
cout << "To stop the program, enter 0." << endl << endl;
cout << "Enter the first number: ";
cin >> numb;
while(true)
{
sum += numb;
if (numb!=0)
{
cout << "Sum equals: " << sum << endl << endl;
cout << "Enter another number: ";
cin >> numb;
}
else
{
cout << "Sum equals: " << sum << endl << endl;
cout << "Entered 0." << endl;
cout << "Press Enter to terminate the app." << endl;
exit(0);
}
}
return 0;
}
You have three options:
trial and error: try to read a float, and in case of error clear the error flag, ignore the bad input and read again. The problem is that you don't know really how many of the input is to be ignored.
read strings: read space delimited strings, try to convert the string using stringstream, and just ignore the full string in case of error. The problem is that if the input starts with a valid float but then contains invalid characters (e.g. 12X4), the invalid part will be ignored (e.g. X4)
control parsing: read space delimited strings, try to convert the string using std::stof(), and check that all characters of the string where successfully read
Here the second approach, with a slightly restructured loop, so that a 0 entry will lead to exiting the loop and not the full program:
string input;
while(cin >> input)
{
stringstream sst(input);
if (sst>>numb) {
sum += numb;
cout << "Sum equals: " << sum << endl << endl;
if (numb==0)
{
cout << "Entered 0." << endl;
break; // exits the while loop
}
cout << "Enter another number: ";
}
else
{
cout << "Ignored entry "<<input<<endl;
}
}
cout << "Press Enter to terminate the app." << endl;
Online demo
If you prefer a more accurate parsing, consider something like:
size_t pos=0;
float xx = stof(input, &pos );
if (pos!=input.size()) {
cout << "error: invalid trailing characters" <<endl;
}
You have to clear the failbit after a failed read. After that, you can read in the invalid stuff into a string (that you just ignore). This function will read in values and add them up until it encounters a 0 or the end of the input stream.
int calc_sum_from_input(std::istream& stream) {
int sum = 0;
// If it couldn't read a value, we just read the thing into here
std::string _ignored;
while(stream) // Checks if the stream has more stuff to read
{
int value;
if(stream >> value)
{
if(value == 0) // Exit if it read the value 0
break;
else
sum += value; // Otherwise update the sum
}
else {
// Clear the failbit
stream.clear();
// Read ignored thing
stream >> _ignored;
}
}
return sum;
}
The logic is basically:
set the initial sum to 0
check if there's stuff to read
if there is, try reading in a value
if successful, check if the value is 0
if it's 0, exit and return the sum
otherwise, add the value to the sum
otherwise, clear the failbit (so that you can read stuff in again) and read the bad value into a string (which gets ignored)
otherwise, return the value

C++ user enters floating point instead of integer

Im trying to get the program to only accept x as an integer then ask for another integer, y. However when i enter a floating point into x it takes the decimal part of the input and makes that the y value. i am unsure of my mistake here.
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int getInt()
{
int x = 0;
while (!(cin >> x))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please input a proper 'whole' number: " << endl;
}
return (x);
}
int toobig()
{
cout << "Your number is too large, please enter something smaller: " << endl;
int x = getInt();
return (x);
}
int toosmall()
{
cout << "your number is negative, please enter a positive number: " << endl;
int x = getInt();
return (x);
}
int main()
{
cout << "your number please:-" << endl;
int x = getInt();
if (x>100000)
{
toobig();
}
else if (x<0)
{
toosmall();
}
int y = 0;
cout << "enter y " << endl;
cin >> y;
cout << "x = " << x << endl;
cout << "y = " << y << endl;
system("PAUSE");
return 0;
}
Most conversions to int stop as soon as they find something that can't be part of an int and only a few conversion functions tell you if they stop before parsing the whole string.
Let's use one of those few, shall we?
int getInt()
{
for ( ; ; ) // loop until user provides something we can use.
// This is dangerous. You probably want to give up after a while.
{
std::string input; // read in as string
if (std::cin >> input)
{
char * endp; // will be updated with pointer to where conversion stopped
errno = 0;
// convert string to int
long rval = std::strtol (input.c_str(), &endp, 10);
if (*endp == '\0') // check whole string was read
{
if (errno != ERANGE) // check converted number did not overflow long
{
if (rval >= std::numeric_limits<int>::min() &&
rval <= std::numeric_limits<int>::max())
// check converted number did not overflow int
// you could replace this min and max with your own passed-in
// min and max values if you want
{
return rval; // return the known-to-be-good int
}
}
}
}
else
{ // note: usually when cin fails to read a string, it's over.
// This is actually a good time to throw an exception because this
// just shouldn't happen.
std::cin.clear(); // but for now we'll just clear the error and
// probably enter an infinite loop of failure
}
// failed for any reason. Blow off all user input and re-prompt
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Please input a proper 'whole' number: " << std::endl;
}
return 0; // to satisfy compiler because a non-void function must always return.
// Never reached because of infinite for loop.
}
since every console input on C++ is treated as a string, then under your getInt() method I would do the following:
int GetInt(istream &stream)
{
char obtainChar; //read a character from input
int x;
stream >> x;
while(stream.fail() || (stream.peek() != '\r' && stream.peek() != '\n'))
{
stream.clear(); //clear the fail state of stream
obtainChar = stream.get(); //read a character from input
while(obtainChar != '\n' && obtainChar != EOF) //while gotten char is not a return key or EOF
obtainChar = stream.get(); //read a character from input iterate up to '\n' or EOF
//displays an error message if there was a bad input (e.g. decimal value)
cerr << endl << "Please input a proper 'whole' number: " << endl;
cout << endl << "Please re-enter x: "; //re-prompt to re-enter a value
x = GetInt(stream); //Try again by calling the function again (recursion)
}
return x; //will return after the user enters ONLY if an integer was inputted
}
the first while is basically saying, if the stream (console input) does fails or the next stream char (.peek()) is not a \r or a \n the clear the stream and get the first character.
while that char is not a \n and not End Of File (EOF) then obtain the next char, so on and so forth.
if a problem occurred then display a error message to the user and re-prompt the user for the value of x.
then call the same function to re-test the input (recursively), if all is well then return the value of x.
you can now call this function to evaluate the value of Y.
NOTE: istream is part of the iostream library is basically cin
NOTE: call the function like so:
int x;
cout << "your number please:-" << endl;
x = GetInt(cin);

Programming Principles and Practice: chapter 4 drill part 1

I just can't seem to get this program to work properly. I can get it to accept two integers and print them to the screen. But I can't get the program to terminate when the '|' is used. Once that its entered it loops infinitely. Here is the code that I have so far:
#include "../../std_lib_facilities.h"
int main()
{
int num1 = 0;
int num2 = 0;
char counter = '\0';
cout << "Please enter two integers and press enter. \n";
bool test = true;
while (counter != '|')
{
cin >> num1 >> num2;
cout << "Your numbers are: " << num1 << " " << num2 << endl;
if (cin.fail())
{
cout << "Goodbye!\n";
test = false;
}
else (counter != '|');
cout << "Enter more numbers or press '|' to exit.\n";
}
system("pause");
}
You are using the wrong condition in your while loop. You are never changing counter so the loop will never end. However you do change test to false in the while loop if the input fails. You can change the condition of the while loop to use test instead like
while(test)
{
//...
}
Since counter is no longer being used you can get rid of it completely.
Please note that unless you change to taking in string and parsing the input any input that will cause cin to fail will end the loop not just a |.

How can you make input take strings and int? c++

is it possible, say your trying to do calculations so the primary variable type may be int... but as a part of the program you decide to do a while loop and throw an if statement for existing purposes.
you have one cin >> and that is to take in a number to run calculations, but you also need an input incase they want to exit:
Here's some code to work with
#include <iostream>
using namespace std;
int func1(int x)
{
int sum = 0;
sum = x * x * x;
return sum;
}
int main()
{
bool repeat = true;
cout << "Enter a value to cube: " << endl;
cout << "Type leave to quit" << endl;
while (repeat)
{
int input = 0;
cin >> input;
cout << input << " cubed is: " << func1(input) << endl;
if (input = "leave" || input = "Leave")
{
repeat = false;
}
}
}
I'm aware they wont take leave cause input is set to int, but is it possible to use a conversion or something...
another thing is there a better way to break the loop or is that the most common way?
One way to do this is read a string from cin. Check its value. If it satisfies the exit condition, exit. If not, extract the integer from the string and proceed to procss the integer.
while (repeat)
{
string input;
cin >> input;
if (input == "leave" || input == "Leave")
{
repeat = false;
}
else
{
int intInput = atoi(input.c_str());
cout << input << " cubed is: " << func1(intInput) << endl;
}
}
You can read the input as a string from the input stream. Check if it is 'leave' and quit.. and If it is not try to convert it to a number and call func1.. look at atoi or boost::lexical_cast<>
also it is input == "leave" == is the equal operator. = is an assignment operator.
int main() {
cout << "Enter a value to cube: " << endl;
cout << "Type leave to quit" << endl;
while (true)
{
string input;
cin >> input;
if (input == "leave" || input == "Leave")
{
break;
}
cout << input << " cubed is: " << func1(atoi(input.c_str())) << endl;
}
}
you can use like
int input;
string s;
cint>>s; //read string from user
stringstream ss(s);
ss>>input; //try to convert to an int
if(ss==0) //not an integer
{
if(s == "leave") {//user don't want to enter further input
//exit
}
else
{
//invalid data some string other than leave and not an integer
}
}
else
{
cout<<"Input:"<<input<<endl;
//input holds an int data
}

Infinite Loop when checking conditions c++ !cin

I'm basically expecting a number as input. The magnitude is negligible now as I know my else if loop works fine. But testing if its a number proves to be a bit trickier. I just want to call the function again and start over if the user enters in something alphanumeric or just plain words. Or pressed enter. Something that is not a number. I tried !cin since I am inputting into int numTemp, but that just results in an infinite loop that spills out "what is the bitrate" countless times. Anyone know what I'm doing wrong? I tried putting cin.clear() and cin.ignore(100, "\n") inside the first if statement but to no avail. Thanks in advance.
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp;
cin >> numTemp;
if (!cin)
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}
You can just read a string from the user instead of an int, and then check it and prompt for new input if you don't like the string (e.g. if it doesn't cleanly convert to a number, which you can check with strtol).
If you want to check whether the input is a number or character, you can use isdigit, but you have to pass it a char and then when it is a digit you can convert it to a int with atoi.
When the statement cin >> numTemp fails due to non-numeric input the character causing the failure is NOT removed from the input stream. So the next time the stream extraction operator is called it will see the same non-numeric input as the last time. To avoid this you need to skip the existing input.
One way of doing this is to use getline() to read a complete line of text before trying to converting it to and integer. The folllowing code snippet illustrates this:
#include <cstdlib>
bool getint(istream& in, int & out) {
string line;
getline(in, line);
char* endptr;
out = strtol(line.c_str(), &endptr, 10);
return endptr!=line.c_str();
}
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp;
if ( !getint(cin, numTemp) && cin )
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}
NOTE: You should also check the status of cin after each read to ensure that some error has not occurred.
i think this will helps
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp = 0;
cin >> numTemp;
if (!numTemp)
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}