Programming Principles and Practice: chapter 4 drill part 1 - c++

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 |.

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

Entering specific character into while loop

I am writing a code for class that asks the user to input a size that is an odd number equal to or greater than 7. I have been able to make that part of my code work successfully. However, the next part consists of asking the user to enter a specific letter, in this case 'c'. If they do not enter 'c' then the loop should ask them to input another character. Whenever I run this code, it is creating an infinite loop whether I enter 'c' or another letter. I think my expression in my second while loop is incorrect, but I haven't been able to find a lot of information regarding this that could help me.
#include <iostream>
using namespace std;
int main() {
int s, l;
cout << "Welcome to the letter printer." << endl;
cout << "Enter the size: " << endl;
cin >> s;
while (s < 7 || s%2==0 || s<0)
{
cout << "Invalid size. Enter the size again: " << endl;
cin >> s;
}
cout << "Enter the letter: " << endl;
cin >> l;
while (l != 'c')
{
cout << "Invalid letter. Enter the letter again: " << endl;
cin >> l;
}
return 0;
}
because you are getting char for int variable
wrong:
int s, l;
right one:
int s;
char l;
what is why it goes on infinite loop in second while
explanation for infinite loop
This is how basic_istream works. In your case when cin >> l gets
wrong input - failbit is set and cin is not cleared. So next time it
will be the same wrong input. To handle this correctly you can add
check for correct input and clear&ignore cin in case of wrong input.
incorporated from here

Error checking two separate inputs

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.

How do I stop this from infinitely repeating, but still keep the loop?

On line 33, there is a break to stop the code from repeating indefinitely, but I would like it to take part in the while loop.
The Code:
#include <iostream>
using namespace std;
int main()
{
while (true){
{
cout << "This program counts by twos to any number that is inputted by the user." << endl;
cout << "Input an even number to start counting." << endl;
int input;
cin >> input;
if (!cin.fail())//fails if input is not an integer
{
if (input < 0)//makes sure all numbers are positive
{
cout << "That is not a positive number. Try again?" << endl;
}
else if (input % 2 != 0) // makes sure all numbers are even
{
cout << "That is not an even number. Try again?" << endl;
}
else{
for (int i = 0; i <= input; i += 2) //uses a for loop to actually do the counting once you know that the number is even.
{
cout << i << endl;
}
}
}
if (cin.fail())//returns this when you input anything other than an integer.
{
cout << "That is not a digit, try again." << endl;
break;
}
}
}
return 0;
}
If you guys could help me find why this repeats, that would really help.
You need to add a break statement after the for loop in order to exit the loop. Without the break the for loop will execute and print your output and then control will fall to the end of the while loop where it will start back at the top of the loop.
I would also suggest changing if (cin.fail()) to just else as you are already checking if (!cin.fail()). You also need to ignore the rest of the input and clear the error flags if you want to loop again.
You also had a extra set of brackets in the while loop. With those changes your code would be:
#include <iostream>
#include <limits>
using namespace std;
int main()
{
while (true)
{
cout << "This program counts by twos to any number that is inputted by the user." << endl;
cout << "Input an even number to start counting." << endl;
int input;
cin >> input;
if (!cin.fail())//fails if input is not an integer
{
if (input < 0)//makes sure all numbers are positive
{
cout << "That is not a positive number. Try again?" << endl;
}
else if (input % 2 != 0) // makes sure all numbers are even
{
cout << "That is not an even number. Try again?" << endl;
}
else{
for (int i = 0; i <= input; i += 2) //uses a for loop to actually do the counting once you know that the number is even.
{
cout << i << endl;
}
break; // exit the while loop
}
}
else //else when you input anything other than an integer.
{
cout << "That is not a digit, try again." << endl;
cin.clear(); // reset the error flags
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // clear any extra input
}
}
return 0;
}
Based on the error message you print, I'm guessing your problem is that you want to give the user a chance to try again to enter a number, but after one failure, it continuously fails no matter what you enter. If that's the case, replace your break with cin.clear(). That will tell the stream that you've recovered from the error and are ready to receive more input.
If you're going to do that, though, your program now has no exit condition, so you'll want to add a break (or return 0) just after the for-loop.

While Loop with LCV of cin won't exit in C++

This is hw. I have asked my professor why the following code won't exit the while loop, and he/she couldn't tell me. My understanding is that once the input stream has no more values to read, the cin will return a value of false, and should cause the while loop to exit. Mine does not. It seems to keep read the input values (a set of integers) process through the loop, then wait for more input. Can anyone tell me why? Below is the code.
# include <iostream>
using namespace std;
int main()
{
int iEvenSum = 0;
int iOddSum = 0;
int iNum;
// prompt user
cout << "Input any set of integers, separated by a space:\n";
cin >> iNum;
cout << "You input: ";
while (cin)
{
cout << iNum << " ";
if (iNum % 2 == 0)
iEvenSum = iEvenSum + iNum;
else
iOddSum = iOddSum + iNum;
cin >> iNum;
}
cout << "\n\nThe sum of Even numbers is " << iEvenSum << "." << endl;
cout << "The sum of Odd numbers is " << iOddSum << "." << endl;
return 0;
}
while(cin) remains true as long as the cin stream is ok and becomes false if cin encounters an end of file character or an error.
In your case, while(cin) will keep on reading the numbers until it encounters an EOF character or an error. Type Ctrl-D when you don't have any more input numbers and it should quit the while loop