I wish to achieve to limit user on only 0 or 1 when program asking for boolean variable.
I'we tried to do so, but it doesn't work. It still keep asking me for typing in.
bool ele;
do{
cout << "Elektro:\t";
cin >> ele;
if (cin && ele == 0 && ele == 1) break;
cin.clear();
cout << "Neveljaven vnos!" << endl;
}while(true);
The good news is, that operator>> for bool by default allows only '0' or '1' as valid input. That means you don't need to explicitly check the value after read - if stream state is ok, so is your bool:
bool ele;
if (!(cin >> ele)) {
// error;
}
The reason you're getting an infinite loop when you enter something like "cvdsavd" is that you only clear the error flags, but don't get rid of the bad charaters. So your loop keeps trying but never can get a valid input. You need to get rid of the garbage:
bool ele;
while (!(std::cin >> ele)) {
std::cout << "Neveljaven vnos!\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Reference for ignore(). You also need to include <limits> for numeric_limits template.
Lp :)
As chris points out, you want to do if (cin && (ele == 0 || ele == 1)) break;
You cant do that :
if (cin && ele == 0 && ele == 1) break;
because its always false because ele cant be in same time 1 or 0 ... It can be only one of this figures.
if(ele == 0 || ele == 1) break;
Related
This small segment of my program seems to cause some problems:
cout << "Would you like to change the values? Type 1 if yes or 2 if no." << endl << "You can also reverse the original vector above by typing 3. \n Answer: ";
cin >> yesorno;
while (yesorno != 1 && yesorno != 2 && yesorno != 3 || cin.fail() )
{
cout << "\n Sorry, didn't catch that. Try again: ";
cin >> yesorno;
}
The loop works fine for all valid integers as far as I know, but when an unvalid value gets declared to yesorno the loop freaks out. For example, if I input the letter A, the loop goes on for infinity.
I guess what I'm asking is, how do I make it so that the user gets unlimited amounts of chances to input a valid value?
I'm pretty new to C++ btw so I am not familiar with all different kinds of public member functions etc.. I've tried cin.clear() but didn't have much success
When you run into error in reading input data, you may use cin.clear() to clear the state of the stream and follow it with a call to cin.ignore() to ignore the rest of the line.
while ( (yesorno != 1 && yesorno != 2 && yesorno != 3) || cin.fail() )
{
cout << "\n Sorry, didn't catch that. Try again: ";
if ( cin.fail() )
{
cin.clear();
cin.input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
cin >> yesorno;
}
Another approach, that I prefer, is to read the input line by line and process each line independently.
std::string line;
while ( getline(cin, line) )
{
std::istringstr str(line);
if ( !(str >> yesorno) || (yesorno != 1 && yesorno != 2 && yesorno != 3) )
{
cout << "\n Sorry, didn't catch that. Try again: ";
continue;
}
else
{
// Got good input. Break out of the loop.
break;
}
}
When the fail bit gets set, you need to clear it before continuing.
while (yesorno != 1 && yesorno != 2 && yesorno != 3 || cin.fail() )
{
if ( cin.fail() ) {
cin.clear();
cin.ignore( std::numeric_limits<std::streamsize>::max() );
}
cout << "\n Sorry, didn't catch that. Try again: ";
cin >> yesorno;
}
So I have this part of code and I have these error than I'm to post how can I fix them . Thx for ur help..
void DisplayMenu()
{
cout <<"Please choose from the following options :\n\n"
<<"1-al.\n"
<<"2-c.\n"
<<"3-v.\n\n"
<<"Or I want to see first :\n"
<<"------------------------\n\n"
<<"4-r.\n"
<<"5-m.\n"
<<"6-k.\n"
<<"7-d.\n"
<<"8-u.\n\n"
<<"Or :\n"
<<"----\n\n"
<<"9-I changed my mind and would like to exit.\n\n";
}
int ChooseFromMenu()
{
int A =0 ;
while ((DisplayMenu() && !(cin >> A ) || (cin.good() && (A < 1 || A > 9))) {
cout << "\nInvalid input!\n"<<endl;
cin.clear();
cin.ignore(1000, '\n');
}
return A;
}
and this is my error list
3 IntelliSense: expected a statement
2 IntelliSense: expected a ')'
Error 1 error C4716: 'DisplayMenu' : must return a value
If you really want to use DisplayMenu in the condition of the while loop, you need to use the comma operator:
int ChooseFromMenu()
{
int A =0 ;
while (DisplayMenu(), (!(cin >> A ) || (cin.good() && (A < 1 || A > 9))) {
cout << "\nInvalid input!\n"<<endl;
cin.clear();
cin.ignore(1000, '\n');
}
return A;
}
This will call DisplayMenu, throw the (non-existant) return value away, and then evaluate the actual condition. Personally however, I would use an infinite loop with a conditional break inside:
int ChooseFromMenu()
{
int A =0;
while (true) {
DisplayMenu();
if ((cin >> A)) {
if (!cin.good() || (1 <= A && A <= 9)) {
return A;
}
}
cout << "\nInvalid input!\n"<<endl;
cin.clear();
cin.ignore(1000, '\n');
}
}
I have split the condition into two embedded ifs because I find that easier to read than combinations of && and ||. (I also like to always use < or <= when combining multiple comparisons - I find it makes it easier to read.)
You're missusing condition in your while loop parameter :
while ((DisplayMenu() && !(cin >> A ) || (cin.good() && (A < 1 || A > 9)))
As you can see from the definition your DisplayMenu is returning void and you are trying to compare it to boolean value ( here -> while ((DisplayMenu() ).
To solve this you can change your DisplayMenu method to just return boolean value :
bool DisplayMenu()
{
// your logic
return true;
}
Complete working example :
#include <iostream>
using namespace std;
int DisplayMenu()
{
cout <<"Please choose from the following options :\n\n"
<<"1-al.\n"
<<"2-c.\n"
<<"3-v.\n\n"
<<"Or I want to see first :\n"
<<"------------------------\n\n"
<<"4-r.\n"
<<"5-m.\n"
<<"6-k.\n"
<<"7-d.\n"
<<"8-u.\n\n"
<<"Or :\n"
<<"----\n\n"
<<"9-I changed my mind and would like to exit.\n\n";
return 1;
}
int ChooseFromMenu()
{
int A =0 ;
if ((DisplayMenu() && !(cin >> A )) || (cin.good() && (A < 1 || A > 9))) {
cout << "\nInvalid input!\n"<<endl;
cin.clear();
cin.ignore(1000, '\n');
}
return A;
}
You forgot a parenthesis in the while loop in ChooseFromMenu(). That is probably causing 2 of the errors. Since return true didn't work, you probably forgot to change the method header from void to boolean. (cin >> A) also returns void.
Can you not use cin and then cin.fail() in the same line like this? Is there a cleaner or more standard way to do this type of error checking upon input?--perhaps not using a do-while.
do {
cin.clear();
cout << "\nPlease enter the size of the array (1-10): ";
} while (cin >> array_size && array_size <= 1 || array_size >= 10 || cin.fail());
This one works:
do {
cout << "Please input #: ";
if (cin.fail()){
cin.clear();
cin.ignore(80, '\n');
}
cin >> kids_total;
} while (cin.fail() || kids_total <= 0);
cin >> array_size && array_size <= 1 || array_size >= 10 || cin.fail()
Say you've got a letter next in cin, cin >> array_size evaluates false so the && short-circuit evalusation skips over array_size <= 1 to test:
array_size >= 10: might be uninitialised memory read ==> undefined behaviour, otherwise presumably false
cin.fail() - definitely true
...unless there's undefined behaviour - and maybe even then - the loop will continue without having removed the letter from cin, only to fail again immediately.
Check cin.ignore for a way to remove input that's failed parsing, or use std::getline(std::cin, my_string), std::istringstream iss(my_string); if (iss >> array_size etc. for a way to guarantee the entire line's thrown away on bad input....
For comparison, this is pretty robust and IMHO intuitive if verbose. If doing it more than once, just create a function....
while (true)
{
std::cout << "Please input #: ";
if (std::cin >> kids_total)
{
if (kids_total > 0)
break;
std::cout << "Value must be > 0, please try again.\n";
}
else if (std::cin.eof())
{
// rare for keyboard input - e.g. ^D on UNIX/Linux, ^Z Windows
// can happen with pipes/redirects - e.g. echo 10 20 | ./my_app
std::cerr << "expected value for kids_total but encountered end of input\n";
exit(EXIT_FAILURE);
}
else
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
The following code contains a logical error
every time i run it and enter 1 or 0 the code
in the while loop is still executed.
can someone tell me why?
bool getmove()
{
bool move;
cout << "Would you like to make the first move?(1 for yes 0 for no)\n";
cin >> move;
while(move != 1 || move != 0 || !cin.good())
{
if(!cin.good())
{
cout << "ERROR please try again\n";
cin.clear();
cin.ignore(80,'\n');
cin >> move;
}
else
{
cout << "Invalid input please try again\n";
cin >> move;
}
}
return move;
}
Look at this line:
while(move != 1 || move != 0 || !cin.good())
It will always be the case that move != 1 || move != 0 (because it can't be both).
Furthermore, you'll avoid some trouble by reading in something like a string and testing that, rather than relying on casting.
If you're trying to write a function which can validate the input of a boolean value, your code can be simplified to:
bool getmove()
{
bool move;
cout << "Would you like to make the first move?(1 for yes 0 for no)\n";
while (!(cin >> move))
{
cout << "Invalid input please try again\n";
cin.clear();
cin.ignore(80, '\n');
}
return move;
}
It is important to realize that while (!(cin >> move)) will repeat the loop until a valid boolean value can be read from the console and written into move.
bool choose() {
int answer = 0;
while(answer != 1 || answer != 2) {
cout << endl << "Do you want to encrypt(enter 1) or decrypt(enter 2)?" << endl;
cin >> answer;
}
if(answer == 1) return true;
return false;
}
What is the best way to read from line and compare input with integers?
I know ways cin , gets , getline(cin, answer) .
Which should I use and why?
At the moment, this way is not working, because when i enter 1 or 2, it still stays in while.
Your condition is incorrect. By De Morgan's laws, you should be using && instead.
while(answer != 1 && answer != 2) {
You're reading the value correctly. However, the loop condition is wrong; it should be
while(answer != 1 && answer != 2)
Using || makes the condition always true, since no number is equal to both 1 and 2.
This code is a very good candidate for do-while loop, and if you use that you're not required to initialize the variable answer.
int answer; //= 0; no need to initialize!
do {
cout<<"Do you want to encrypt(enter 1) or decrypt(enter 2)?"<<endl;
cin >> answer;
}while(answer != 1 && answer != 2);
And of course, you need to use && as others has already pointed out. :-)
By the way, what would happen if user entered any non-integer input such as hgjkhg? cin>>answer would fail to read the input and it will remain there forever, and the flag of cin will be set failure, and cin will not be able to read futher input. That means, the loop will never exit!
To avoid this, and to make the code more robust and complete you should write it as:
int answer = 0;
while(answer != 1 && answer != 2) {
cout<<"Do you want to encrypt(enter 1) or decrypt(enter 2)?"<<endl;
if ( !(cin >> answer) )
{
cin.clear(); //clear the failure flag if there is an error when reading!
std::string garbage;
std::getline(cin, garbage); //read the garbage from the stream and throw it away
}
}
Yes. You can use your while loop instead of do-while. All that you need to add the if(!(cin>>answer)) { ... } in your code. :-)