String to float using stringstream

时光总嘲笑我的痴心妄想 提交于 2019-12-22 05:09:30

问题


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:

  1. output two times the value of input floats
  2. report invalid inputs
  3. continue looking for floats even after encountering invalid inputs
  4. 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!