If I were to ask the user a question and the response can be either a string or an int, I would have to determine if it were an int or a string before I can pass the input to a variable right? How would I do that?
-
Strings are a superset of numbers, at least in terms of holding the data. – chris Mar 27 '15 at 00:47
-
http://en.cppreference.com/w/cpp/string/byte/isdigit -- `Isdigit()` – Jagannath Mar 27 '15 at 00:48
-
If you exclusively want `int`, you can use the `input bits – Mar 27 '15 at 00:50
-
I'd say this answer leads you to one of the best viable approaches: [How to test whether stringstream operator>> has parsed a bad type and skip it](http://stackoverflow.com/questions/24504582/how-to-test-whether-stringstream-operator-has-parsed-a-bad-type-and-skip-it). Anyway, considered that there are so many approaches available to solve your problem (dependent from more certain use cases), it's not possible to give a concise answer at all. – πάντα ῥεῖ Mar 27 '15 at 00:53
-
@jafar _"the `input bits "_ What are these? That's new to me. Please explain! – πάντα ῥεῖ Mar 27 '15 at 00:55
-
http://www.cplusplus.com/reference/ios/ios/fail/ – Mar 27 '15 at 00:58
-
I'm kind of surprised no one has mentioned `std::stoi`. – chris Mar 27 '15 at 01:00
-
From your question, if your program asks "how old are you?" is `20` or `twenty` correctly possible answers? – Mar 27 '15 at 01:02
-
@jafar I much prefer http://en.cppreference.com/w/cpp/io/basic_ios/fail. But that's merely opinion based, and you should extend about the actual behavior a bit more in your answer for my taste. – πάντα ῥεῖ Mar 27 '15 at 01:05
5 Answers
The normal way is to read in a string, check if the string contains an integer, and then if it does, convert the contents to an integer. The goal of the if(inttest>>myint)
is to attempt to read into an integer. If it succeeds, the input-string must have been an integer. If it fails, it wasn't an integer.
std::mystring;
int myint;
std::cin >> mystring;
std::istringstream inttest(mystring);
if (inttest>>myint) {
//it's an integer
std::cout << myint;
} else {
//it's a string
std::cout << mystring;
}
The reason for the additional istringstream is that cin >> var
eats the input, so if it fails to convert, it is already gone. Thus the need to cache the input locally, attempt to convert it, and if that failed then use the cached value as-is.

- 64,318
- 19
- 100
- 158
-
why there the need for an additional `istrtingstream`? I thought the result of `std:cin>>var` should be enough. – vsoftco Mar 27 '15 at 00:49
-
1`cin >> var` eats the input, so if it fails to convert, it is already gone. Thus the need to cache the input locally, attempt to convert it, and if that failed then use the cached value as-is. – Remy Lebeau Mar 27 '15 at 01:02
-
This method doesn't seem to work for me (maybe I'm doing it wrong) `int main() { string input; //get the input from the user cout << "Enter either an int or a string "; cin >> input; istringstream inttest(input); if (inttest>>input) { //it's an integer cout << "it's an int"; } else { //it's a string cout << "it's a string"; } return 0; }` – Pierre Gaboriau Mar 27 '15 at 01:24
-
@PierreGaboriau: the goal of `if(inttest>>myint)` is to attempt to read into an _integer_. If it succeeds, the input-string must have been an integer. If it fails, it wasn't an integer. Your code there reads into a string instead of an integer, which always succeeds, because a string can read anything. – Mooing Duck Mar 27 '15 at 16:24
You could read the input with string::getline()
and then use the string as input string stream to try to read a number.
bool got_string = true;
string line;
int number;
if (getline(cin, line)) { // if read is successful
istringstream str(line);
if (str >> number) // and if the format corresponds to a number
got_string = false;
}

- 68,716
- 7
- 72
- 138
This depends on what you accept. If the answer should be only an int
, then you can test the result of if(cin>>var)
(where var
is int
). If it is false
, then the readout was un-successful, which means you din't introduced a valid int
.
In other words, the stream "detects" whether its last operation was successful or not.

- 55,410
- 12
- 139
- 252
I think this provides for string and integer answers.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
int y;
string answer;
cout<<"how old are you ";
getline(cin,answer);
stringstream ss;
ss<<answer;
//check if its int
if(ss>>y)
cout<<"you are "<<y<< "(int)"<<endl;
else //its string
cout<<"you are "<<answer<<" (string)"<<endl;
return 0;
}
-
_"the `input bits "_ What are these? That's new to me. Please explain! – πάντα ῥεῖ Mar 27 '15 at 00:56
I don't believe this is the best way to do this, but a comment on an existing answer caught my eye...
cin >> var
eats the input, so if it fails to convert, it is already gone. Thus the need to cache the input locally, attempt to convert it, and if that failed then use the cached value as-is. – Remy Lebeau
...so I thought I'd show that it is sometimes possible to recover from a parsing error - resetting the istream
so further input can be attempted. Using this approach, you can first try to read an int
, and if that fails read a word of text into a std::string
. It's important to do it that way because reading say "46"
into a std::string
works just fine so doesn't tell you it could have been parsed as an int
, but reading "fifty"
into an int
fails then you know you'll have to try getting it into a std::string
.
Though not relevant for inputting an age, more generally one negative with this approach is - well - negatives. Trying to parse "-five"
as an int
will consume the -
then fail, leaving only the five
to be parsed as a std::string
. Depending on the type of stream in use, you may be able to record the stream position with .tellg
, then if it fails restore the position with seekg
.
Anyway, enough blabbing - here's some code, where I use one std::istringstream
in place of std::cin
so I can run it on ideone.com
without manual input, but the point is that it doesn't need an extra std::istringstream
with a copy of a line of input:
#include <iostream>
#include <sstream>
#include <string>
void f(const char* p)
{
std::istringstream iss(p);
int num;
if (iss >> num)
std::cout << num << " (an int)\n";
else
{
iss.clear(); // recover from parsing int failure above
std::string word;
if (iss >> word)
std::cout << word << " (a string)\n";
}
}
int main()
{
f("five");
f("35");
}
Output:
five (a string)
35 (an int)
Available on ideone.com

- 102,968
- 15
- 177
- 252