2010-02-25 3 views
2

Я использую boost libs для C++, и функция lexical_cast ведет себя действительно странно. Если я делаю lexical_cast («0.07513994»), он отлично работает, но если я использую свою переменную, которую мне нужно преобразовать, она выдает исключение bad_lexical_cast. Вот код:boost lexical_cast throws exception

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

Что я здесь делаю неправильно? Я ценю любую помощь, спасибо

+1

Просьба показать полный ввод, который находится в потоке. –

+0

Какова фактическая стоимость линии? Он 'lexical_cast' будет бросать, если он не сможет преобразовать. Проверьте строковое значение 'word' перед вызовом лексического актера, и вы, вероятно, обнаружите, что это не то, что вы считаете. –

+0

Может ли быть, что строка заканчивается пробелом типа '\ n'? –

ответ

2

Ваша проблема, вероятно, в том, что цикл обрабатывается еще раз, чем вы ожидаете. В последний раз по циклу слово «прочитать» не удается, установив бит fail в iss, и это то, что пока (iss) проверяет. Чтобы исправить это, вам нужно сделать что-то вроде этого.

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

Большое спасибо Michael – Student

+6

Или избавитесь от цикла do-while и используйте простой цикл while с 'while (iss >> word) {...}'. В этом цикле do-while условие в основном избыточно. –

+0

Решение Johannes, безусловно, опрятно. Я просто хотел подчеркнуть, что было не так в оригинальном посте. –

2

В отличие от функций, таких как atof(), который остановить разбор, как только они видят недопустимый символ, lexical_cast требует, чтобы каждый символ входной строки в силе. то есть любое начальное или конечное пространство вызовет его исключение.

Вы хотите посмотреть, какой вход он получает и подрезать соответствующим образом. Вы также должны поймать bad_lexical_cast на всякий случай, если он получит вход, который полностью мусор.

Одним из возможных решений является использование boos.regex или boost.xpressive для извлечения действительной подстроки и передачи результата в lexical_cast.

2

Проблема, вероятно, в том, что вы отправляете пустую строку, когда данных нет.
Вы должны изменить цикл, который используете.

Используйте цикл while {} (а не цикл «do while»). Это позволяет вам читать из потока и проверять его в одном легко читаемом заявлении. Обратите внимание на результат iss >> word - поток. При использовании в этом булевом контексте он проверяется на то, хорошо ли состояние и его значение преобразуется во что-то, что может использоваться условием while. Таким образом, если оператор >> подал заявку на правильную работу, цикл никогда не вводится.

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

Но на самом деле вы даже не нужен лексический оттенок в этой ситуации (если вы не хотите, чтобы проверить, не являющиеся числа с исключением). Стандартный оператор потока преобразует вход в двойной.

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