Cin.clear() issue - c++

Im writing a program that is supposed to accept integers only, I'm currently using
int x;
cin >> x;
while(cin.fail()){
cout << "error, please enter an integer" << endl;
cin.clear();
cin.ignore();
cin >> z;
cout << "you entered" << z << endl;
}
however if i enter a double for example 1.2 the program ignores the decimal point but sets the value of z to 2 and doesnt request user input.
What can i do to stop this?

Before this goes out of hand, here's once again a typical example of an input operation:
#include <string> // for std::getline
#include <iostream> // for std::cin
#include <sstream> // for std::istringstream
for (std::string line; std::cout << "Please enter an integer:" &&
std::getline(std::cin, line); )
{
int n;
std::istringstream iss(line);
if (!(iss >> n >> std::ws) || iss.get() != EOF)
{
std::cout << "Sorry, that did not make sense. Try again.\n";
}
else
{
std::cout << "Thank you. You said " << n << ".\n";
}
}
It will keep asking you for integers until you close the input stream or terminate it in some other way (e.g. by typing Ctrl-D).
You will find hundreds, if not thousands, of variations on this theme on this website.

Related

Always indicate incorrect

Even you answer is correct, it will still indicate it is incorrect .
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main() {
string play;
cout << "Do you want to play? ";
cin >> play;
if (play == "yes") {
cout << "Ok, Let's Get Started! \n";
} else {
cout << "Let's play next time!";
}
string test1;
cout << "What does CPU stand for? ";
cin >> test1;
if (test1 == "central processing unit") {
cout << "Correct!\n";
} else {
cout << "Incorrect!\n";
}
return 0;
}
I try to redo/recode the if else statement but it didn't run. I'm expecting that there some expert can help me.
This statement
cin >> test1;
reads a single word, so it can never read the three words of 'central processing unit'. If you want to read lines of text then use getline
getline(cin, play);
and
getline(cin, test1);

cin.ignore not working: further inputs get skipped even with clear()

I am trying to make a checked bool input, but for some reason it keeps getting into an infinite loop, or (if I move std::cin.ignore() to be first thing executed after std::cin.clear()) asks for phantom input. I tried simple ignore() and ignore(std::numeric_limits<std::streamsize>::max(),'\n') and it still gets into an infinite loop, seemingly skipping cin input
Code:
#include <cstdlib>
#include <iostream>
#include <limits>
int main()
{
std::string testString = "testvar";
bool value = false;
do
{
std::cin.clear();
std::cout << "Enter " << testString << " value (true/false)\n";
std::cin >> std::boolalpha >> value;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
if(!std::cin.fail())
{
break;
}
std::cout << "Error! Input value is not boolean! Try again.\n";
}while(true);
std::cout << value;
}
Your problem here is your order of operations. With
std::cin.clear();
std::cout << "Enter " << testString << " value (true/false)\n";
std::cin >> std::boolalpha >> value;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
You call clear, get input, and then ignore the leftovers. The issue with that is if the get input part fails, then the ignore the leftovers will also fail as the stream is in a failed state. What you need to do is get the input, clear any error away, and then ignore an extra input. That would look like
std::cout << "Enter " << testString << " value (true/false)\n";
std::cin >> std::boolalpha >> value;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
but this will break how your loop works. To get that working, you can use
do
{
std::cout << "Enter " << testString << " value (true/false)\n";
if (std::cin >> std::boolalpha >> value)
break;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "Error! Input value is not boolean! Try again.\n";
} while(true);

Why cin inside while doesn't stop to get user input?

I'm starting now with C++, so I imagine this is gonna be a very easy-newbie question.
Well, why the "cin >> x" line inside while doesn't stop the loop to get the user input (if the user inputs a character, in place of a number)?
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
int x = 0;
cout << "Please, enter x: ";
cin >> x;
while (!cin)
{
cout << "Please, it must be a number!\n";
cin >> x;
}
cout << "Thanks!.";
cin.ignore();
cin.ignore();
}
I'm barely two days studiying C++, so I'm completely blind about what "cin" really is. I tried with "cin.sync()" and "cin.clear()", but still no luck.
And I know it is impossible to do something like "cin=true", or "cout << cin".
Well, your program should be corrected slightly
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
int x = 0;
cout << "Please, enter x: ";
cin >> x;
while (!cin)
{
cin.clear();
cin.ignore(10000, '\n');
cout << "Please, it must be a number!" << endl;
cin >> x;
}
cout << "Thanks!.";
}
This way it works as expected. More info about it here. In general, you need to clear all the errorneous stuff from cin.
if user input a character than it will take the ascii value of character so it will not stop.
To stop the loop enter 0.

Over looping (Cout) in C++

#include <iostream>
#include <string>
#include <cctype>
using namespace std;
char hold;
string name;
char num1;
char num2;
int main() {
cout << "Hello!\n";
cout << "Tell me your name?: ";
cin >> name;
cout << "Well well well, if it isn't "<< name << "!\n";
cout << "Enter a NUMBER " << name << ": ";
cin >> num1;
while(!isdigit(num1)) {
cout << "Enter a NUMBER " << name << ": ";
cin >> num1;
}
cin >> hold;
system("pause");
return 0;
}
The problem is, it is overlooping the cout. How do I fix it?
Thanks.
A better way is to use std::stringstream (note: include sstream)
int getNumber()
{
std::string line;
int i;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> i)
{
if (ss.eof())
{
break;
}
}
std::cout << "Please re-enter your input as a number" << std::endl;
}
return i;
}
This replaces your while loop, and you make the call after asking for a number as you already figured out how to do.
The following is a shortened version of the original attempt. However, as with the original, it only checks a single character.
If I changed num1 to be an int then i'd need to check whether the input was valid as #Dieter Lucking mentioned.
#include <iostream>
using namespace std;
int main() {
char num1;
do {
cout << "\nEnter a number: ";
cin >> num1
} while(!isdigit(num1));
}
A bit of a variation on staticx's solution, which will pass Dieter Lücking's echo "" | test line.
I use an istringstream and get input until no more standard input or I get valid input. I pushed it all into a templated Get function that can be used for any type; you just need to give it a prompt for the user:
Get() function
template<typename T>
void Get(T& toSet, std::string prompt) // read from cin
{
std::string nextIn;
cout << prompt;
getline(cin >> std::ws, nextIn);
istringstream inStream(nextIn);
while(cin && !(inStream >> toSet))
{
inStream.clear();
cout << "Invalid Input. Try again.\n" << prompt;
getline(cin >> std::ws, nextIn);
inStream.str(nextIn);
}
if (!cin)
{
cerr << "Failed to get proper input. Exiting";
exit(1);
}
}
And you'd use it like so:
int myNumber = 0;
Get(myNumber, "Please input a number:");
Full code:
Live Demo
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template<typename T>
void Get(T& toSet, std::string prompt) // read from cin
{
std::string nextIn;
cout << prompt;
getline(cin >> std::ws, nextIn);
istringstream inStream(nextIn);
while(cin && !(inStream >> toSet))
{
inStream.clear();
cout << "Invalid Input. Try again.\n" << prompt;
getline(cin >> std::ws, nextIn);
inStream.str(nextIn);
}
if (!cin)
{
cerr << "\nFailed to get proper input. Exiting\n";
exit(1);
}
}
int main()
{
string name;
int num1 = -1;
cout << "\nHello!\n";
Get(name, "\nTell me your name?:");
cout << "\nWell well well, if it isn't "<< name << "!\n";
Get(num1, std::string("\nEnter a NUMBER, ") + name + ": ");
cout << "\nYou entered number: " << num1 << std::endl;
return 0;
}

C++ Check if input is float using only #iostream

I would like to validate if the user input is Float or not, the program checks if the input was float and prints "Number is fine" else it prints "Number is not fine" and it continue the loop without taking the failed attempt in consideration of the loop, in other way it gives him another try to enter a float number instead.
The problem is that the program goes on infinity loop once the user enter a "Character". what i actually want it to do is just printing "Number isn't fine" then continue.
Can anybody tell me why does this happen, also please consider not to use any additional libraries.
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int x;
float num;
cout << "Please enter the amount of numbers you wish to enter" << endl;
cin >> x;
cout << "Please enter the numbers" << endl;
for(int i=0; i < x;) {
if(!(cin >> num)) {
cout << "Number isn't fine" << endl;
continue;
}
cout << "Number is fine" << endl;
++i;
}
system("pause");
}
#Steve your solution worked by using both cin.clear() and cin.ignore
#AndyG Thanks for your help but unfortunately im limited to the simplest way.
Here is the final code if somebody wanted to know how it looks in the future.
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int x;
float num;
cout << "Please enter the size of numbers" << endl;
cin >> x;
cout << "Please enter the numbers" << endl;
for(int i=0; i < x;) {
if(!(cin >> num)) {
cin.clear();
cin.ignore();
cout << "not a float number" << endl;
continue;
}
cout << "Number is fine" << endl;
++i;
}
system("pause");
}
If cin >> num fails to read a number then the stream is put into the failed state (that is, the failbit is set), and it doesn't read past the character that caused it to fail. You never do anything to clear() the fail state or to ignore() the bad data, so you loop forever.