Для чего устанавливать поток в состояние fail()?

110
18 августа 2021, 17:00

Из книги "Программирование. Принципы и практика использования с++".

void fillVector(istream &ist, vector<int>&v, char terminator)
{
    int i=0;
    while(ist>>i)
        v.push_back(i);
    if(ist.eof())
        return;
    if(ist.bad())
        error("поток ist поврежден");
    if(ist.fail())
    {
        ist.clear();
        char c;
        ist>>c;
        if(c!=terminator)
        {
            ist.unget();
            ist.clear(ios_base::failbit);
        }
    }
}

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

Answer 1

Сначала показалось, что не имеет смысла написать ответ, но все же, думаю, будет полезно:

//если введено не число
if(ist.fail()) 
    {
        // установить бит `ios_base::goodbit` 
        ist.clear(); 
        char c;
        // и прочитать следующий символ
        ist>>c;
        // если этот символ не совпадает с
        //символом, переданный в аргумент функции     
        if(c!=terminator)
        {
            //приводим поток в состояние
            //когда еще не был прочтен символ
            ist.unget();
            //и очистив все биты, установим 
            //бит `ios_base::failbit`            
            ist.clear(ios_base::failbit);
        }
    }

То же самое можно выразить и по другому:

if (ist.fail()) {
    ist.clear();
    if (ist.peek() != terminator)
        ist.setstate(std::ios_base::failbit);
}

А значит: если не удалось прочитать число, то приводим состояние потока в good, чтобы проверить является ли следующий символ terminator ом? Если да, то все хорошо, в обратном случаи снова устанавливаем бит fail. Для наглядности можем добавить проверочный код:

vector<int> v;
char t = ';';
fillVector(cin, v, t);  
if (cin.fail()) {
    cout << "установлен бит fail, поскольку был введен символ\n";
    cin.clear(); //очистим, чтобы прочитать этот символ
    cout  << char(cin.get()) << "а не символ " << t;
}
READ ALSO
Сортировка строки,содержащей числа,не используя стандартные библиотечные функции.C++

Сортировка строки,содержащей числа,не используя стандартные библиотечные функции.C++

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

215
Для какого типа представления графа написан этот алгоритм (BFS)

Для какого типа представления графа написан этот алгоритм (BFS)

На emaxx начал изучать алгоритмыДошел до графов

122
Assertion failed: !hook.is_linked() в Boost

Assertion failed: !hook.is_linked() в Boost

Не могу понять из-за чего выскакивает исключение "Assertion failed: !hookis_linked(), file d:\boost_1_71_0\boost_1_71_0\boost\intrusive\detail\generic_hook

168