Consider the following code which takes an integer input and then prints the cin stream state:
#include <iostream>
using namespace std;
int main()
{
int number;
cout<<"Enter a number \n";
cin>>number;
cout<<cin.rdstate()<<endl;
return 0;
}
If the number entered is "zzzz" then the rdstate returns a value of 4.
If the number entered is "10zzzz" then the rdstate returns a value of 0, number has a value of 10, and the input stream has "zzzz" in it.
My question is:
1. Why isn't a input of "10zzzz" treated as an invalid input (atleast one of the failure bits should have been set.)
2. What is an elegant solution to detect and handle this situation.
Thanks!!!
First of all I would like to ask what you are trying to do with:
cout<<cin.rdstate()<<endl;
Read this page for the proper use of rdstate()
http://www.cplusplus.com/reference/iostream/ios/rdstate/
second:
to check wetether the input is either stringtype or integer type you might want to add something extra wich will convert the input string to integer data and will respond with an error message when feeded an invalid input.
therefor this will help you out:
int main() {
string input = "";
// How to get a string/sentence with spaces
cout << "Please enter a valid sentence (with spaces):\n>";
getline(cin, input);
cout << "You entered: " << input << endl << endl;
// How to get a number.
int myNumber = 0;
while (true) {
cout << "Please enter a valid number: ";
getline(cin, input);
// This code converts from string to number safely.
stringstream myStream(input);
if (myStream >> myNumber)
break;
cout << "Invalid number, please try again" << endl;
}
cout << "You entered: " << myNumber << endl << endl;
// How to get a single char.
char myChar = {0};
while (true) {
cout << "Please enter 1 char: ";
getline(cin, input);
if (input.length() == 1) {
myChar = input[0];
break;
}
cout << "Invalid character, please try again" << endl;
}
cout << "You entered: " << myChar << endl << endl;
cout << "All done. And without using the >> operator" << endl;
return 0;
}
Related
When cin>>(int) and cin>>(string) are called, when the first input is not correct for integer, it seems that cin>>(string) will fail to retrieve the second input even if it is correct string.
The source code is simple as:
cout<<"Please enter count and name"<<endl;;
int count;
cin>>count; // >> reads an integer into count
string name;
cin>>name; // >> reades a string into name
cout<<"count: "<<count<<endl;
cout<<"name: "<<name<<endl;
The test cases are:
Case 1: Type characters(which not fit for int) and characters
Please enter count and name
ad st
count: 0
name:
Case 2: Type numbers and characters
Please enter count and name
30 ad
count: 30
name: ad
Case 3: Type numbers and numbers (which could be taken as strings)
Please enter count and name
20 33
count: 20
name: 33
A stream has an internal error flag that, once set, remains set until you explicitly clear it. When a read fails, e.g. because the input could not be converted to the required type, the error flag is set, and any subsequent reading operation will not even be tried as long as you do not clear this flag:
int main() {
stringstream ss("john 123");
int testInt;
string testString;
ss >> testInt;
if (ss) {
cout << "good!" << testInt << endl;
} else {
cout << "bad!" << endl;
}
ss >> testString;
if (ss) {
cout << "good!" << testString << endl;
} else {
cout << "bad!" << endl;
}
ss.clear();
ss >> testString;
if (ss) {
cout << "good:" << testString << endl;
} else {
cout << "bad!";
}
}
Output:
bad!
bad!
good:john
You can check for the input statement if it is succeeded or not with the
cin.good() method
If the input statement fails it returns false else true. Here is a small example:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int x;
// prompt the user for input
cout << "Enter an integer: " << "\n";
cout << "cin.good() value: " << cin.good() << "\n";
// get input
cin >> x;
cout << "cin.good() value: " << cin.good() << "\n";
// check and see if the input statement succeeded
if (!cin) {
cout << "That was not an integer." << endl;
return EXIT_FAILURE;
}
// print the value we got from the user
cout << x << endl;
return EXIT_SUCCESS;
}
Output:
Enter an integer:
cin.good() value: 1
asd
cin.good() value: 0
That was not an integer.
I am new here and new to c++ as well.
I just started my first year at school and I have been given an assignment in which one of the questions is to convert an octal number to a decimal number using Char only.
The task is to create a program that receives chars from the user and where the length of the number is not known in advance. The user should press '\t' in order to start calculating to a decimal number.
I don't really understand how it works.Because if I code a simple algorithm such as:
char ch;
cin<<ch;
cout>>ch>>endl;
and I give it 67, it will print 6 only. That means that it reads every char separately, doesn't it?
Could someone please help me understand it by showing me the algorithm for this problem or explaining to me how char works?
Thanks a lot
Coral
You will get enough info on how to read from stdin char by char.
please go through this link.
http://www.cplusplus.com/forum/articles/6046/
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string input = "";
// How to get a string/sentence with spaces
cout << "Please enter a valid sentence (with spaces):\n>";
getline(cin, input);
cout << "You entered: " << input << endl << endl;
// How to get a number.
int myNumber = 0;
while (true) {
cout << "Please enter a valid number: ";
getline(cin, input);
// This code converts from string to number safely.
stringstream myStream(input);
if (myStream >> myNumber)
break;
cout << "Invalid number, please try again" << endl;
}
cout << "You entered: " << myNumber << endl << endl;
// How to get a single char.
char myChar = {0};
while (true) {
cout << "Please enter 1 char: ";
getline(cin, input);
if (input.length() == 1) {
myChar = input[0];
break;
}
cout << "Invalid character, please try again" << endl;
}
cout << "You entered: " << myChar << endl << endl;
cout << "All done. And without using the >> operator" << endl;
return 0;
}
In the below code, I'm running into an error when I try to get the user to input their name. My program just skips it over and goes right over to making the function calls without allowing the user to enter their name. Despite the error, my program is compiling. I'm not sure what's going wrong as I wrote that part based off other examples I found on here. Any suggestions?
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
char showMenu();
void getLottoPicks(int[]);
void genWinNums(int[]);
bool noDuplicates(int[]);
const int SIZE = 7;
int main()
{
int userTicket[SIZE] = {0};
int winningNums[SIZE] = {0};
char choice;
string name;
srand(time(NULL));
do
{
choice = showMenu();
if (choice == '1')
{
cout << "Please enter your name: " << endl;
getline(cin, name);
getLottoPicks(userTicket);
genWinNums(winningNums);
for (int i = 0; i < SIZE; i++)
cout << winningNums[i];
}
} while (choice != 'Q' && choice != 'q');
system("PAUSE");
return 0;
}
Added the code for showMenu:
char showMenu()
{
char choice;
cout << "LITTLETON CITY LOTTO MODEL:" << endl;
cout << "---------------------------" << endl;
cout << "1) Play Lotto" << endl;
cout << "Q) Quit Program" << endl;
cout << "Please make a selection: " << endl;
cin >> choice;
return choice;
}
And getLottoPicks (this part is very wrong and I'm still working on it):
void getLottoPicks(int numbers[])
{
cout << "Please enter your 7 lotto number picks between 1 and 40: " << endl;
for (int i = 0; i < SIZE; i++)
{
cout << "Selection #" << i + 1 << endl;
cin >> numbers[i];
if (numbers[i] < 1 || numbers[i] > 40)
{
cout << "Please choose a number between 1 and 40: " << endl;
cin >> numbers[i];
}
if (noDuplicates(numbers) == false)
{
do
{
cout << "You already picked this number. Please enter a different number: " << endl;
cin >> numbers[i];
noDuplicates(numbers);
} while (noDuplicates(numbers) == false);
}
}
}
After doing cin >> choice; inside char showMenu(), if a user inputs 1[ENTER], the char consumes 1 character from cin, and the newline stays inside the stream. Then, when the program gets to getline(cin, name);, it notices that there's still something inside cin, and reads it. It's a newline character, so getline gets it and returns. That's why the program is behaving the way it is.
In order to fix it - add cin.ignore(); inside char showMenu(), right after you read the input. cin.ignore() ignores the next character - in our case, the newline char.
And a word of advice - try not to mix getline with operator >>. They work in a slightly different way, and can get you into trouble! Or, at least remember to always ignore() after you get anything from std::cin. It may save you a lot of work.
This fixes the code:
char showMenu()
{
char choice;
cout << "LITTLETON CITY LOTTO MODEL:" << endl;
cout << "---------------------------" << endl;
cout << "1) Play Lotto" << endl;
cout << "Q) Quit Program" << endl;
cout << "Please make a selection: " << endl;
cin >> choice;
cin.ignore();
return choice;
}
from looking at code showMenu function has problem. and it's not returning asccii equivalent of '1' that is: 31 integer. try printing value returned by showmenu. you will get that
UPDATE:
It is because cin in delimited by ' '(whitespace) and getline by '\n' character, so when enter name and press enter cin in showmenu will consume whole string except '\n' from istream and that is read by getline. to see this when it ask for choice enter string like 1 myname (1 whitespace myname)and press ENTER will display name. now cin will read 1 in choice and myname in name by getline.
I am new to C++ coding.
I have noticed that if I enter multiple characters for a character variable then the test program given below goes into an infinite loop. I am not able to debug this issue properly. Can someone help me see how the flow of the program goes when such input is entered. I doubt about some unsafe conversions happening.
There is a possibility that the overflow values are taken as input for next integer variable, but I am checking for variable in a loop and asking the user to
re-enter a value is invalid. The program does not halt for taking new input for number. Instead it infinitely prints "Enter a Number". Why is it that the cin is not working for
taking the new input? Is there some modification in this program that can rectify this error?
#include <iostream>
int main()
{
char name;
int number=-1;
cout << "Enter a character: \n";
cin >> name; //Use input like abc here
cout << "number = " << number;
while (number == -1)
{
cout << "Enter a number: \n";
cin >> number; // This never waits for user input
}
return 0;
}
Output
Enter a character:
ytc
number = -1Enter a number:
Enter a number:
Enter a number:
When the user enters mutiple characters on the first query, only the first one is extracted and stored in name.
After that, the loop is entered. The first character is read, and it is not a number, thus the stream goes into a bad state. All subsequent reads fail, so the value of number never changes, and you have an infinite loop.
The following program will do what you want:
#include <iostream>
int main() {
char name = '\0';
int number = -1;
std::cout << "Enter a character: " << std::endl;
std::cin >> name;
std::cout << "You entered " << name << std::endl;
while(number == -1) {
std::cout << "Enter a number: " << std::endl;
if(!(std::cin >> number)) {
if(std::cin.eof()) {
std::cout << "User pressed CRTL+d" << std::endl;
break;
}
std::cout << "This was not a valid number - try again: " << std::endl;
std::cin.clear();
std::cin.get(); // extract one character
}
else
std::cout << "You entered " << number << std::endl;
}
}
The condition if(!(std::cin >> number)) checks if the extraction was successful. If not, an error-message is printed, the stream-state is cleared, and one character extracted. The latter is done to prevent an infinite loop, because if we never extract the bad character, we will get the same error over and over again.
Note that the extraction std::cin >> number will try to extract the longest string that represents a number. If the user inputs 234t23432, then it will extract 234, because the t is the first character that can not be interpreted as part of the number.
There is no guaranteed method to clear an input stream. You can write code to clear but there's no surety that it will work. Because in standard C/C++ input streams are buffered. The keypresses are buffered by operating system, not by the program. You can recursively call cin.get() to make sure that all the data in the buffer is consumed. See the snippet below
char name = 0;
int number = -1;
std::cout << "Enter a character: " << std::endl;
std::cin >> name;
std::cout << "You entered " << name << std::endl;
// Clear the stream
while( !std::cin.eof() && std::cin.get() != '\n' );
std::cout << "Enter a number: " << std::endl;
std::cin >> number;
return 0;
void get_english_input() {
string input = " ";
stringstream my_string(input);
int ft;
double in;
while(true) {
cout << "Enter an integer value of feet." << endl;
getline(cin, input);
my_string << input;
if(my_string >> ft)
break;
cout << "Invalid input! Please try again." << endl;
}
cout << "you entered " << ft << " as the int value for feet." << endl;
/*while(true) {
cout << "Enter a double value of inches." << endl;
getline(cin, input);
my_string << input;
break;
cout << "Invalid input! Please try again." << endl;
}
cout << "we are done entering english input" << endl;
cout << "feet = " << ft << endl;
cout << "inches = " << in << endl;*/
}
This code is supposed to test if the input is an integer by trying to put the contents of my_string into ft. If I enter a letter instead of an integer I get the error message "Invalid input! Please try again," which is what is supposed to happen. The problem is, after I get that message once, I will get it for every input after that, even if the next input is valid.
Someone suggested that I should use std::cin.clear(); to clear the error-flags. I tried putting it before the getline() and it did not change the problem. Was I using this incorrectly?
You could reset the error state of my_string:
my_string.clear();
my_string.ignore( /* big number of choice */ );
But I think it would be easier here just to reinitialize it every time:
while(true) {
cout << "Enter an integer value of feet." << endl;
getline(cin, input);
stringstream my_string(input);
Check out lexical_cast from Boost ...
The brute-force solution is to dump your input into a std::string, then loop over the string and check if each character is between 0 and 9.
It's not the most elegant approach. But it's simple and stupid. :-)
bool isnum(char c)
{
if(! ( c <= '9' && c >= '0'))
{
return false;
}
return true;
}
bool has_int(std::string &s)
{
for( int i = 0; i < s.length(); i++)
{
if( ! isnum(s[i])
{
return false;
}
}
return true;
}
I think
mystring >> ft
will always evaluate to be true (maybe not if mystring was empty). The operation will still work whether or not mystring actually contains a number or not.
One idea is to
size_t found=input.find_first_not_of("0123456789 ");
if (found!=string::npos)
{
cout << "Invalid input! Please try again."
}
Adapted from here.