преобразовать строку в символы и целые (комбинация) с помощью istringstream

Я думаю, что есть какой-то тривиальный очень глупый баг, но я не могу его прибить. Любой совет?

string stuff = "5x^9";
istringstream sss(stuff);
double coeff;
char x, sym;
int degree;

sss >> coeff >> x >> sym >> degree;
cout << "the coeff " << coeff << endl;
cout << "the x " << x << endl;
cout << "the ^ thingy " << sym << endl;
cout << "the exponent " << degree << endl;

Выход:

the coeff 0
the x
the ^ thingy 
the exponent 1497139744

Так и должно быть, я полагаю

the coeff 5
the x x
the ^ thingy ^
the exponent 9

person alienflow    schedule 27.03.2018    source источник
comment
Не удается воспроизвести ideone.com/CH8wLu . Как я уже задавал в своем предыдущем вопросе, уверены ли вы, что исходная строка не содержит пробелов?   -  person Bob__    schedule 27.03.2018
comment
@Bob__ уверен на 100%, я ввел ровно 5x^9, без пробелов   -  person alienflow    schedule 27.03.2018
comment
@Bob__ но я вижу, что это работает для тебя! Так что не так??   -  person alienflow    schedule 27.03.2018
comment
Это кажется связанным: stackoverflow.com/questions/19725070/ . Здесь я могу воспроизвести вашу проблему, хотя здесь, заменив x на z, его можно будет проанализировать.   -  person Bob__    schedule 27.03.2018


Ответы (1)


Ваша проблема связана с наличием символа x после числа, которое вы хотите извлечь из вашей строки ("5x"), что вызывает проблемы синтаксического анализа в некоторых реализациях библиотек.

См., например. Несоответствие между оператором istream›› (double& val) между libc++ и libstdc++ или Characters, извлеченные istream ›› double для получения более подробной информации.

Этого можно избежать, либо изменив имя неизвестного (например, x -> z), либо используя другой метод извлечения, например такой:

#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>

int main(void)
{
    std::string stuff{"5x^9"};

    auto pos = std::string::npos;
    try {
        double coeff = std::stod(stuff, &pos);
        if ( pos == 0  or  pos + 1 > stuff.size() or stuff[pos] != 'x' or stuff[pos + 1] != '^' )
            throw std::runtime_error("Invalid string");

        int degree = std::stoi(stuff.substr(pos + 2), &pos);
        if ( pos == 0 )
            throw std::runtime_error("Invalid string");

        std::cout << "coeff: " << coeff << " exponent: " << degree << '\n';
    }
    catch (std::exception const& e)
    {
        std::cerr << e.what() << '\n';
    }    
}
person Bob__    schedule 27.03.2018
comment
На самом деле, когда я явно объявил x = 'x', все сработало! - person alienflow; 29.03.2018