boost lexical_cast throws exception

6.7k Views Asked by At

I'm using boost libs for c++ and the function lexical_cast behaves really weird. If I do lexical_cast("0.07513994") it works fine, but if I use my variable which I need to convert, it throws the bad_lexical_cast exception. Here is the code:

string word;
istringstream iss(line);
do
{
   string word;
   iss >> word;        
   double x;
   x = lexical_cast<double>(word);   
   cout << x << endl;
} while (iss);

What am I doing wrong here? I appreciate any help, thanks

3

There are 3 best solutions below

2
On BEST ANSWER

Your problem is probably that the loop is processed one more time than you expect. The last time through the loop, the read to word fails, setting the fail bit in iss, which is what while(iss) is checking. To fix it you need to do something like this.

string word;
istringstream iss(line);
do
{
   string word;
   iss >> word; 
   if(iss)
   {       
     double x;
     x = lexical_cast<double>(word);   
     cout << x << endl;
   }
} while (iss);
0
On

The problem is probably that you are sending an empty string when there is no data left.
You should change the loop you are using.

Use the while {} loop (not the 'do while' loop). This allows you to read from the stream and test it in a single easy to read statement. Note the result of iss >> word is the stream. When used in this boolean context it is tested to see if the state is good and its value converted into something that can be used by the while condition. Thus if the operator >> filed to work correctly then the loop is never entered.

istringstream iss(line);
string        word;
while(iss >> word)
{
    double x = lexical_cast<double>(word);   
    cout << x << endl;
}

But really you don't even need the lexical cast in this situation (unless you want to test for non numbers with an exception). The standard stream operator will convert the input into a double.

istringstream iss(line);
double        word;
while(iss >> word)
{
    cout << word << endl;
}
if (iss.fail())
{    /* Failure to convert input to a double */
}
0
On

Unlike functions such as atof() which stop parsing as soon as they see an invalid character, lexical_cast requires that every character in the input string be valid. i.e. any leading or trailing spaces will cause it to throw an exception.

You want to see what kind of input it is getting and trim it accordingly. You should also catch bad_lexical_cast just in case it does get input which is completely garbage.

One possible solution is to use boos.regex or boost.xpressive to extract a valid sub-string and pass the result to lexical_cast.