Can I tell if std :: string is a number using stringstream?

Apparently, this is allowed to work on display if the string is numeric, for example, "12.5" == yes, "abc" == no. However, I do not see any changes.

std::stringstream ss("2"); double d; ss >> d; if(ss.good()) {std::cout<<"number"<<std::endl;} else {std::cout<<"other"<<std::endl;} 
+8
c ++ numbers stringstream words
source share
4 answers

You must use istringstream so that it knows that it is trying to istringstream input. Also, just check the result of the extraction directly, and do not use good later.

 #include <sstream> #include <iostream> int main() { std::istringstream ss("2"); double d = 0.0; if(ss >> d) {std::cout<<"number"<<std::endl;} else {std::cout<<"other"<<std::endl;} } 
+4
source share

Do not use good ()! Check for a thread:

 if (ss) 

It tells you well if any of eofbit, badbit or failbit are installed, and fail () tells you about badbit and failbit. You almost never care about eofbit unless you already know that the stream has failed, so you almost never want to use the good.

Note that testing the stream directly, as described above, is exactly equivalent:

 if (!ss.fail()) 

And vice versa,! ss is equivalent to ss.fail ().


Combining extraction into a conditional expression:

 if (ss >> d) {/*...*/} 

It corresponds exactly to:

 ss >> d; if (ss) {/*...*/} 

However, you probably want to check if the complete string can be converted to double, which is a bit more active. Use boost :: lexical_cast, which already handles all cases.

+7
source share

If you want to check if string contains only a number and nothing (except spaces), use this:

 #include <sstream> bool is_numeric (const std::string& str) { std::istringstream ss(str); double dbl; ss >> dbl; // try to read the number ss >> std::ws; // eat whitespace after number if (!ss.fail() && ss.eof()) { return true; // is-a-number } else { return false; // not-a-number } } 

ss >> std::ws important for accepting numbers with a trailing space, for example "24 " .

The ss.eof() check is important for rejecting strings such as "24 abc" . This ensures that we reach the end of the line after reading the number (and spaces).

Wiring harness:

 #include <iostream> #include <iomanip> int main() { std::string tests[8] = { "", "XYZ", "a26", "3.3a", "42 a", "764", " 132.0", "930 " }; std::string is_a[2] = { "not a number", "is a number" }; for (size_t i = 0; i < sizeof(tests)/sizeof(std::string); ++i) { std::cout << std::setw(8) << "'" + tests[i] + "'" << ": "; std::cout << is_a [is_numeric (tests[i])] << std::endl; } } 

Output:

  '': not a number 'XYZ': not a number 'a26': not a number '3.3a': not a number '42 a': not a number '764': is a number ' 132.0': is a number '930 ': is a number 
+5
source share
 int str2int (const string &str) { stringstream ss(str); int num; if((ss >> num).fail()) { //ERROR: not a number } return num; } 
-one
source share

All Articles