Как использовать независимый от локали strtod с отчетом об ошибках

Я использую strtod() для преобразования строки в десятичную. Так как мне нужно выдать ошибку за неправильный ввод / недопустимые символы, у меня нет другого выбора. Однако проблема в том, что на strtod() влияют локали. Так что "." становится недопустимым символом, когда программа запускается в другой локали

Если я использую решение, подобное этому:

std::istringstream text(iterator->second.c_str());
text.imbue(std::locale::classic());
double result;
text >> result;

вообще невозможно проверить на неверный ввод.

Какое решение может предоставить мне оба?

2 ответа

Решение

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

Вот небольшой пример, демонстрирующий преобразование:

bool convert(const std::string & text)
{
    if (text = "")
        return false;
    std::istringstream iss(text);
    iss.imbue(std::locale::classic());
    double result;
    iss >> result;
    if (iss.eof())
        return true;
    else
        return false;
}

int main()
{
    std::cout << convert("123.456") << std::endl;
    std::cout << convert("123.456abc") << std::endl;
    std::cout << convert("123.456e5") << std::endl;
    std::cout << convert("e5") << std::endl;
    return 0;
}

Выход:

1
0
1
0

Живой пример

Вы можете проверить правильность ввода, протестировав text на наличие ошибок и того, что он дошел до конца ввода:

text >> result;
bool ok = text && text.eof();

Пример: http://coliru.stacked-crooked.com/a/758b769f26567d1e

Другие вопросы по тегам