boost lexical_cast создает исключение - PullRequest
2 голосов
/ 25 февраля 2010

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

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

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

Ответы [ 3 ]

2 голосов
/ 25 февраля 2010

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

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

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

2 голосов
/ 25 февраля 2010

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

Используйте цикл 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 */
}
2 голосов
/ 25 февраля 2010

Ваша проблема, вероятно, в том, что цикл обрабатывается еще раз, чем вы ожидаете. В последний раз в цикле происходит сбой чтения слова, устанавливая бит сбоя в iss, который проверяет while (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);
...