简体   繁体   中英

String to float using stringstream

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;
}

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM