2014-12-19 4 views
0

У меня вопрос о поведении потока, см. Следующий пример. Я ожидал, что ss_char и ss_int будут иметь состояние eof, но только ss_int будет иметь состояние eof.неожиданное поведение при чтении символа из istringstream

Мой вопрос: почему это не ss_char eof state? Не могу ли я использовать оператор >>, только функцию istringstream :: get(), но зачем тогда читать значение успешно?

Выход:
значение символ: а
INT значение: 42

ss_char ВФ: ложь // почему ложь?
ss_int eof: true

Извините за мой плохой английский. Я работаю над улучшением своего английского языка.

#include <iostream> 
#include <sstream> 

int main(int /*argc*/, char const * /*argv*/[]) 
{ 
    char c; 
    int num; 
    std::istringstream ss_int("42"); 
    std::istringstream ss_char("a"); 

    if (ss_char >> c) 
    { 
     std::cout << "char value: " << c << std::endl; 
    } 
    else 
    { 
     std::cout << "cannot read char" << std::endl; 
    } 

    if (ss_int >> num) 
    { 
     std::cout << "int value: " << num << std::endl; 
    } 
    else 
    { 
     std::cout << "cannot read int" << std::endl; 
    } 

    std::cout << std::endl; 

    std::cout << "ss_char eof: " << std::boolalpha << ss_char.eof() << std::endl; // why false 
    std::cout << "ss_int eof: " << std::boolalpha << ss_int.eof() << std::endl; 

    return 0; 
} 
+3

Разница заключается в том, что 'ss_char' нужно только извлечь один символ, в то время как' ss_int' продолжит сканирование, пока не найдет пробел или конец файла. – 0x499602D2

ответ

0

CppReference говорит: «Эта функция только сообщает о состоянии потока в установленный самой последней операции ввода/вывода, он не проверяет соответствующий источник данных, например, если последняя I O был/а. get(), который возвращает последний байт файла, eof() возвращает false. Следующий get() ничего не читает и устанавливает eofbit. Только тогда eof() возвращает true. "

oefbit повернется, когда операция чтения попытается прочитать за пределами конца файла, но не тогда, когда она точно читается до конца файла, не пытаясь идти дальше. Когда вы читаете символ, он знает, что он должен читать один байт, поэтому эта операция чтения в порядке, позиция чтения вперед 1 байт идет до конца, но пусть говорят, что поток все еще не заметил, что это действительно конец, это будет, если вы попытаетесь прочитать что-то еще. Когда вы читаете целое число, он пытается читать дальше 42, потому что длина целого неясна, это могло быть 42901, поэтому он должен читать до тех пор, пока не увидит пробел и конец строки, или, в конце концов, конец file/stream, если читать нечего.

И результат оператора >> - это сам поток. Когда он преобразуется в void * (или bool, зависит от C++ 11 или предыдущего), он работает как! Fail(), поэтому он сообщает вам, была ли операция чтения или записи в порядке, независимо от того, достигли ли они конца файла (следующая операция чтения завершится неудачей, если она будет в конце).

0

Состояние EOF фактически не происходит, пока вы не попытаетесь прочитать минута конец потока.

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

С другой стороны, извлечения int пытается использовать как можно больше цифр. Он читает 4 и 2, а затем пытается снова прочитать, чтобы увидеть, есть ли другая цифра для потребления, делает попытку прочтения конца в этом случае. Он замечает, что вход подходит к концу и таким образом завершает преобразование 42.

0

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

При извлечении int парсер пытается вытащить столько символов, чтобы сформировать номер. это приводит к тому, что целочисленное извлечение попадает в eof в тестовом примере.

+0

Похоже, мы все ответили на это примерно то же самое время :-) – Orrkid

Смежные вопросы