问题
I found this code online as a template for doing a string to float/int/double conversion. It's only here so I have something to reference for the question....
I want to have a user enter a number as a string, convert it to a float, test it for success and drop out if entry was 'Q' or print "Invalid input" if it wasn't the 'Q'uit character and return for more input.
What's the syntax for a conversion fail test? Would it be ss.fail() ?
// using stringstream constructors.
#include <iostream>
#include <sstream>
using namespace std;
int main () {
int val;
stringstream ss (stringstream::in | stringstream::out);
ss << "120 42 377 6 5 2000";
/* Would I insert an
if(ss.fail())
{
// Deal with conversion error }
}
in here?! */
for (int n=0; n<6; n++)
{
ss >> val;
cout << val*2 << endl;
}
return 0;
}
回答1:
Your code isn't very helpful. But if I understand you right do it like this
string str;
if (!getline(cin, str))
{
// error: didn't get any input
}
istringstream ss(str);
float f;
if (!(ss >> f))
{
// error: didn't convert to a float
}
There's no need to use fail.
回答2:
Actually, the simplest way to do string to float conversion is probably boost::lexical_cast
#include <string>
#include <boost/lexical_cast.hpp>
int main() {
std::string const s = "120.34";
try {
float f = boost::lexical_cast<float>(s);
} catch(boost::bad_lexical_cast const&) {
// deal with error
}
}
Obviously, in most cases, you just don't catch the exception right away and let it bubble up the call chain, so the cost is much reduced.
回答3:
Some of the features requested by the original question are:
- output two times the value of input floats
- report invalid inputs
- continue looking for floats even after encountering invalid inputs
- stop after seeing a 'Q' character
I think the following code meets the above request:
// g++ -Wall -Wextra -Werror -static -std=c++11 -o foo foo.cc
#include <iostream>
#include <sstream>
void run_some_input( void )
{
std::string tmp_s;
int not_done = 1;
while( not_done && getline( std::cin, tmp_s ) )
{
std::stringstream ss;
ss << tmp_s;
while( ! ss.eof() )
{
float tmp_f;
if ( ss >> tmp_f )
{
std::cout << "Twice the number you entered: "
<< 2.0f * tmp_f << "\n";
}
else
{
ss.clear();
std::string tmp_s;
if( ss >> tmp_s )
{
if( ! tmp_s.compare( "Q" ) )
{
not_done = 0;
break;
}
std::cout << "Invalid input (" << tmp_s << ")\n";
}
}
}
}
}
int main( int argc __attribute__ ((__unused__)), char **argv __attribute__ ((__unused__)) )
{
run_some_input();
}
Here's a sample session:
$ ./foo
1
Twice the number you entered: 2
3 4
Twice the number you entered: 6
Twice the number you entered: 8
5 bad dog Quit 6 8 Q mad dog
Twice the number you entered: 10
Invalid input (bad)
Invalid input (dog)
Invalid input (Quit)
Twice the number you entered: 12
Twice the number you entered: 16
来源:https://stackoverflow.com/questions/12947607/string-to-float-using-stringstream