While loop not terminating C++ - c++

I would like to keep inputting integers to the P1 vector until a break point in this case 'q' or 'Q' is entered. The program when ran goes crazy into an endless loop once the break condition is met. Any ideas on a work around, all I can see is that because the 'q' or 'Q' is a character the integer vector is taking this as an input when the while loop runs at which point it endless loops?
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//Declaring Polynomial 1 and 2
vector<int> P1;
vector<int> P2;
int x = 0;
int y = 0;
while (x != 'q'||x != 'Q') {
cout << "Please enter in the first polynomial one value at a time (Press Q when done)...";
cin >> x;
P1.push_back(x);
}
//Also tested with a do while same problem
/*do
{
cout << "Please enter in the first polynomial one value at a time (Press Q when done)...";
cin >> x;
P1.push_back(x);
} while (x != 'q');*/
//Ignore this is for next part of program
vector<int> Res((P1.size() + P2.size()) + 1);
cout << P1.size() << "," << P2.size() << "," << Res.size();
return 0;
}

(x != 'q'||x != 'Q') <---- here is an error, it is obviously always true: when x==q -> true, because (x! = 'Q') == true, and the other way around. change || to &&.

The condition:
(x != 'q' || x != 'Q')
is always true resulting in an endless loop. Why that is in more details:
The x integer variable is initialized to 0. Then you check if x is different than 'q' which represents an integer value of 111. It is not equal to that value so the expression of x != 'q' is true. Then you check if x is not equal to 'Q' character which represents an integer value of 85. It is not equal to that value so the expression of x != 'Q' is also true. We end up with a condition of (true || true) which is always true.
Integral values are implicitly convertible to boolean values where 0 represents false and any other number represent true. Try something like this instead:
char c = 'y';
while (std::cin && (c == 'y' || c == 'Y')) {
// do work
std::cout << "Do you want to repeat the input? y / n?";
std::cin >> c;
}
That being said you don't need the "stdafx.h" header.

First I think you should not use int x
Second just like Ron said change || to &&
Anyway, Ron gave an example and it works.

Related

Code keeps printing "1" when everything is correct

The code runs and all but it doesn't print out the vowels, but instead prints a "1".
#include <iostream>
#include <string>
using namespace std;
int countVowels(string sentence,int numVowels)
{
for(int i =0; i<sentence.length(); i++)
{
if((sentence[i]==('a'))||(sentence[i]==('e'))||(sentence[i]==('i'))||(sentence[i]==('o'))||(sentence[i]==('u'))||(sentence[i]==('A'))||(sentence[i]==('E'))||(sentence[i]==('I'))||(sentence[i]==('O'))||(sentence[i]==('U')))
numVowels=numVowels+1;
}
}
int main()
{
string sentence;
int numVowels = 0;
do{
cout << "Enter a sentence or q to quit: ";
cin >> ws;
getline(cin,sentence);
}
if(sentence == 'q'|| sentence == 'Q');
cout << "There are " << countVowels << " vowels in your sentence." << endl;
return 0;
}
The output should be like this:
Enter a sentence or a to quit: I like apples!
There are 4 vowels in your sentence, and 11 letters.
Enter a sentence or q to quit: q
Bye!
My problem:
Can someone explain to me why it keeps printing a "1", and my "if" statement where I am supposed to assign the hotkey "q" to exit the program isn't working. When I run the program I get an error at the if statement saying "no match for operators=="
I usually don't like just providing a full solution, but since your question shows you have made a good effort, here's how I would write it (well, not quite, I simplified a little to be more beginner friendly):
#include <algorithm>
#include <iostream>
#include <string>
bool isVowel(char c)
{
// A simple function that returns true if the character passed in matches
// any of the list of vowels, and returns false on any other input.
if ( 'a' == c ||
'e' == c ||
'i' == c ||
'o' == c ||
'u' == c ||
'A' == c ||
'E' == c ||
'I' == c ||
'O' == c ||
'U' == c) {
return true; // return true if it's a vowel
}
return false; // remember to return false if it isn't
}
std::size_t countVowels(std::string const& sentence)
{
// Use the standard count_if algorithm to loop over the string and count
// all characters that the predicate returns true for.
// Note that we return the resulting total.
return std::count_if(std::begin(sentence),
std::end (sentence),
isVowel);
}
int main() {
std::string sentence;
std::cout << "Please enter a sentence, or q to quit: ";
std::getline(std::cin, sentence);
if ( "q" == sentence ||
"Q" == sentence) {
// Quit if the user entered a string containing just a single letter q.
// Note we compare against a string literal, not a single character.
return 0;
}
// Call the counting function and print the result.
std::cout << "There are "
<< countVowels(sentence) // Call the function on the input.
<< " vowels in your sentence\n";
return 0;
}
Hopefully the comments make it all clear.
Now you might have been told that you can't use the standard algorithms (std::count_if), since part of the exercise seems to be to write that. Well I'll leave that to you. Your current version is close to correct, but remember to return the result. And you don't really need to pass in the numVowels count, just create that within the function, and remember to return it.

Confusion with the OR logical Operator in a Loop

A bit earlier on an IRC channel, someone asked a question about his code - essentially, his program was running on an infinite loop:
#include <iostream>
using namespace std;
int main()
{
cout << "This program adds one to your input." << endl;
char choice = 'n';
int num = 0;
while (choice != 'y' || choice != 'Y')
{
cout << "Enter number: ";
cin >> num;
num++;
cout << "Your number plus 1 is: " << num << endl;
cout << endl << "Continue/Quit? Type 'Y' to quit, any other key to continue: ";
cin >> choice;
}
cout << "By choosing 'Y', you exit the loop." << endl;
return 0;
}
Paying attention to the loop header, it seems that the loop should be working perfectly fine, but whenever it comes time for me to enter Y or y in order to exit, the loop keeps running. Considering that the while loop won't evaluate the expression to the right if the one on the left is true, this makes it especially confusing. But in any case, even if I input Y or y the loop keeps running! I'd like a somewhat in-depth explanation of why this happens, I've been trying to reason it out, look back in my textbook etc. but I can't seem to understand why... I've changed the OR into an AND, but what makes OR so bad and causes it to malfunction?
Thanks all.
Condition (choice != 'y' || choice != 'Y') is always true, so loop will run indefinetely.
If choice == 'y', then you get (false || true) == true;
if choice == 'Y', then you get (true || false) == true.
You need to use while(choice != 'y' && choice != 'Y') instead, in this case you exit loop only if you get 'y' or 'Y', otherwise you get (true && true) and continue.
The OR operator between many statements returns true if at least 1 of the statements is true, no matter if the others are false or true. In your case, choice != 'y' || choice != 'Y' will be evaluated like this:
First statement is true: Execute while loop.
First statement is false: Check if the second statement is true.
Second statement is true: Execute while loop.
Second statement is false: don't execute while loop.
Specifically, when the compiler arrives at choice != 'y', if choice == 'Y', then it will still execute, because choice != 'y' is true, in fact choice is equals to Y, so it's different from y.
If, on the other hand, choice is equals to y, then it will check if the second statement is true, but we know that choice is equals to y, so choice is different from Y, and so on...
You make a mistake,you should change "||" to "&&"

how to only allow 3 values in a "if" and "while" statement to allow the loop to exit

I'm just stuck on some logic statements.
specifically the ones that are in the function char GetInteger() so how would I only allow 3 values to cause the loop to exit.
char GetInteger( /* out */ char& usrinput)
{
do
{
cin >> usrinput;
cin.ignore(200,'\n');
if (usrinput != 0 || usrinput != 1 || usrinput != 2)
{
cout << "Invalid Input." << userinput << " Try Again\n";
}
} while(usrinput != 0 || usrinput != 1 || usrinput != 2);
return userInput;
}
Two issues with this code:
First userinput has a type of char. So when you read from a stream you read a single character (after dropping white space). So when a user types 1<enter> you get the character '1' in the variable userinput. Note the character '1' is not the same as the number 1.
Thus your test should be:
userinput != '1';
Secondly your boolean logic is wrong. When first learning it is sometimes easier to state the problem as a list of values that you would like to be acceptable (not the unacceptable ones).
You want the conditions to be false if the userInput has one of your accepted values (any good value will fail the test and thus not invoke the bad code). The first step to this is to get a true if any of your values are valid.
// If any value is good then true.
userinput == '1' || userinput == '2' || userinput == '3'
To invert this just add a not to the expression.
if (! (userinput == '1' || userinput == '2' || userinput == '3') )
Note: in boolean logic
!(A || B) => (!A && !B)
So you could re-write the above as:
if (userinput != '1' && userinput != '2' && userinput != '3')
I think this was your main mistake you converted the == into != but did not convert the || into &&.
I would also suggest that you could simplify this (as you may get more valid result) byconverting this into a range based test.
if (userinput < '1' || userinput > '3')
{
// Test Failed.
}
Additionally. Since you have the test in two places. You should yank it outinto its own function. Then you can call the function to do the test.
bool isUserInputValid(char userInput)
{
return userInput >= '1' && userInput <= '3';
}
Now we can re-write your original function as:
char GetInteger( /* out */ char& usrinput)
{
do
{
cin >> usrinput;
cin.ignore(200,'\n');
if (!isUserInputValid(userinput))
{
cout << "Invalid Input." << userinput << " Try Again\n";
}
} while(!isUserInputValid(userinput));
return userInput;
}
First of all, you should use int instead of string as you are reading integer.
You can use while(1) instead of putting condition in while. Inside while loop, if your selection is 0 or 1 or 2, you can simply break the loop.

Infinite while loop happens when asking user for 2 numbers

I'm trying to implement a simple game where user is asked for 2 valid integer coordinates between 0 and 10. (int row, int column)
An exemple of what I would realize is:
Insert coordinates: 4C
*Error, number of row and column must be integer
Insert coordinates: 44 2
*Error, number of row or column are too high
Insert coordinates: 4 3
The coordinates you entered are (4,3)
I realized all of these with a do-while cycle.
int r,c;
do{
cout<<"Insert coordinates: ";
cin>>r>>c;
if (cin.fail())
{
cout << "ERROR: Number of row and column must be integer." << endl << endl;
}
if ((r<0 || r>10) || (c<0 || c>10)
{
cout << "*Error, number of row or column are too high [0-10]" << endl << endl;
}
cout<<endl;
}
while (((r<0 || r>10)||(c<0 || c>10)) || cin.fail());
This code doesn't work properly. If I enter 2 numbers between 0 and 10, it works. If I enter a number bigger then 10, it also works. But if I entered a character the program goes into an infinite loop, and does not work properly.
How to implement this to handle errors with character input? Is there a way to recognize, and remain inside the while cycle, if user inputs a character?
If you enter a letter instead of a number, then that letter is not extracted from the input buffer, so your code will continue to fail forever.
If the input fails (why not use e.g. if (!(cin >> r >> c))?) then you can skip the line by doing calling the ignore function:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
You also want to clear the failbit as it's not cleared automatically, this is done with the clear function.
You can also bypass this problem by getting the whole line, and using std::istringstream for the parsing:
do
{
std::string line;
if (!std::getline(std::cin, line))
... // Could not read from input
std::istringstream iss(line);
int r, c;
if (!(iss >> r >> c))
... // Failed to parse as numbers
...
} while (...);
You could simply check if characters were entered, for example:
if (x >= 0x41 && x <= 0x7A)
cout<<"error, you entered a letter";
(((r<0 || r>10)||(c<0 || c>10)) || cin.fail());
change to
(((r>0) && (r<10))||((c>0) && (c<10))) //It will work, no need to check cin.fail();
If cin fails then it might produce errors in buffer so better to quit the program..
The program goes into an infinite loop because you never clear the fail state. You can simplify your entire loop:
#include <iostream>
using namespace std;
int main()
{
int r = -1;
int c = -1;
bool valid = false;
do
{
cout<<"Insert coordinates: ";
if (cin >> r >> c)
{
if (r >= 0 && r <= 10 && c >= 0 && c <= 10)
{
valid = true;
}
}
else
{
cin.clear();
cin.ignore();
}
if (!valid)
{
cout << "ERROR: Number of row and column must be an integer between 0 and 10." << endl;
}
} while (!valid);
cout << "You entered (" << r << ", " << c << ")" << endl;
return 0;
}

Char validator will not only accept lower and upper case M/F

Hey im trying to validate a char to limit it to accpeting an m or f for male or female. But it doesnt pass the while condition even when m or f is pressed and keeps looping the question.
Can anybody help me with this.
Thanks in advance.
Here is my code:
char Validator :: getChar(string q)
{
char input;
do
{
cout << q.c_str() << endl;
cin >> input;
}
while(!isalpha(input) && "M"||"F"||"m"||"f");
return input;
}
The "M"||"F"||"m"||"f" part of your code doesn't do what you think it does. What it does is check the ADDRESSES of those string constants. Since they are all non-NULL, this expression simply returns true, so your condition, essentially becomes: while(!isalpha(input) && true) which is the same as while(!isalpha(input)).
Try this instead:
char Validator::getChar(const string &q)
{
char input = 0;
do
{
cout << q << endl;
cin >> input;
}
while((input != 'M') && (input != 'F') && (input != 'm') && (input != 'f'));
return input;
}
The expression in the while doesn't mean what you think it does. First, the ! does not apply to the entire expression, and second, "equality" is not an implicit test. You need to write out everything you mean.
To test for equality, use the == or != operators. You have to use the operators on every value you want to test; the operator doesn't "distribute" over a list of values like it would in ordinary English. Write your condition like this:
while (input != 'M' && input != 'F' && input != 'm' && input != 'f');
You can see that the isalpha call isn't necessary; if input isn't equal to any of the listed values, then it doesn't really matter whether it's an alphabetical character.
Another way to write it is this:
while (!(input == 'M' || input == 'F' || input == 'm' || input == 'f'));
Notice that I've another set of parentheses around the internal terms so that the ! operator applies to the entire expression instead of just the first term.
Just for an alternative approach to the terminating condition:
char Validator::getChar(const string &q)
{
const std::set<char> valid_chars { 'M', 'm', 'F', 'f' };
char input = 0;
do
{
cout << q << endl;
cin >> input;
}
while (!valid_chars.count(q));
return input;
}