rdstate () после извлечения значения из потока строк (и логического типа) - PullRequest
0 голосов
/ 09 ноября 2018

(/ edit: добавлен 3-й выпуск)

Чтобы легко анализировать примитивные типы из различных источников (а также, возможно, некоторые объекты, перегружающие операторы << & >>), я создал эту функцию-шаблон:

#include <sstream> 
#include <iostream> //only for the debug trace
#include <typeinfo> //only for the debug trace

template<typename T>
static inline bool getValue(std::string value, T& result)
{
    //std::cout << "getValue : '" << value << "'" << std::endl;
    //std::cout << "type : " << typeid(T).name() << std::endl;

    std::stringstream ss(value);
    ss >> std::boolalpha >> result;

    //std::cout << "result : " << result << std::endl;
    //std::cout << "ss.rdstate() : " << ss.rdstate() << std::endl;

    return ss.good();
}

Эта шаблонная функция принимает строку и пытается извлечь значение в соответствии с заданным ссылочным типом.

Выход:

Для логического значения со значением "true":

getValue : 'true'
type : b
result : 1
ss.rdstate() : 0

Для логического значения со значением "1":

getValue : '1'
type : b
result : 0
ss.rdstate() : 4

Для целых:

getValue : '60'
type : i
result : 60
ss.rdstate() : 2

Для строки со значением "бла": (да, я знаю, бесполезно для строки, но если я хочу выполнить цикл по нескольким параметрам с различными типами ...)

getValue : 'blah'
type : Ss
result : blah
ss.rdstate() : 2

У меня здесь 2 вопроса:

1) логические значения

Чтобы иметь возможность читать строки значений "true" или "false", мне пришлось добавить этот манипулятор "std :: boolalpha". Но тогда я не могу успешно разобрать '0' или '1' для типа bool.

2) Флаг штата

В случае ошибки при разборе (например, с логической проблемой), rdstate возвращает 4 (то есть «ошибка»). В случае, если это правильно, он либо вернет 0 (хорошо) для логического значения; или '2' (т.е. "eof") для целых чисел или строки. Может кто-нибудь объяснить, почему такая разница между этими типами? Должен ли я считать "Eof" как правильно? Я предполагаю, что да.

Документация оператора >> (http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/) гласит, что failbit установлен для: «Либо никакие символы не были извлечены, либо извлеченные символы не могут быть интерпретированы как допустимое значение соответствующего типа»

Таким образом, пустая строка вызовет сбой. (проверено, и rdstate равен 6, т.е. eof | fail);

3) дополнительный вопрос: значение в случае ошибки:

Тестируя, я пытался установить ошибку при установке int. Я вызвал мою функцию с инициализированным нулем int и пустой строкой:

int timeout=0;
getValue ("", timeout);

getValue : ''
type : i
result : 60000
ss.rdstate() : 6

Это значение в 60 000 выглядит для меня очень странно. это соответствует значению init другого int .. WTF! Конечно, я проверяю результат, но некоторые другие пользователи не могут. Должен ли я включить исключения на failbit?

...