Почему getline() не принимает постоянный istream?

Основной вопрос здесь, я пытаюсь изучить основы iostream.

Мне сказали создать функцию чтения строк const istream&. т. е. validateFile (const istream & is)

Я понял, что не могу использовать функцию getline() с const istream& в качестве первого аргумента. Мне интересно, почему. Я думал, что просто читаю istream, изменяет ли его функция getline()?

Можно ли вообще получать информацию из постоянного потока?


person Pico    schedule 31.01.2014    source источник
comment
Он считывает строку из потока, поэтому меняет свое состояние.   -  person juanchopanza    schedule 01.02.2014


Ответы (3)


Идея потока состоит в том, чтобы последовательно считывать из него некоторые данные, каждый раз продвигая свой внутренний указатель. Перемещая этот указатель, вы изменяете объект потока. Вы не можете читать из const потоков (если вы не const приведете их, но этого делать не следует).

EDIT: На самом деле нам все равно, использует ли фактический объект потока, скрытый за интерфейсом istream, какие-то "внутренние указатели" или нет. Если быть точным, важно то, что поток меняет свое состояние, когда вы его читаете, потому что в следующий раз, когда вы его читаете, вы получаете другой результат (вы читаете следующее из потока). И если вам дан объект const, это означает, что вы не должны изменять его состояние.

Кроме того, есть причина, по которой нельзя просто получить данные из потока и ничего не менять. В случае файловых потоков следующая вещь, которую вы хотите прочитать из потока, может даже не находиться в памяти, объекту потока может потребоваться сначала прочитать его с диска, обновить свои буферы и т. д. (EDIT:< /strong> Но это не меняет внешне видимое состояние объекта, так что на самом деле это не очень хороший аргумент.Читайте о ключевом слове mutable, чтобы узнать больше.)

person atablash    schedule 31.01.2014
comment
@MemyselfandI Вы правы, istream - это просто интерфейс, и то, использует ли фактический файловый поток какой-то изгиб указателя на свой буфер или нет, является деталью реализации. - person atablash; 01.02.2014

Можно получить данные из потока const, но вам нужно выполнить чтение через класс streambuf, которым он управляет:

#include <sstream>
#include <iostream>
#include <cstdio>

int main()
{
    const std::istringstream strm("Const stream");
    std::streambuf* buf = strm.rdbuf();

    char c;
    while ((c = buf->sbumpc()) != EOF)
        std::cout << c;
}
person jrok    schedule 31.01.2014
comment
Это следует рассматривать как ОШИБКУ В СПЕЦИФИКАЦИИ. -1, чтобы противостоять глупым плюсам. - person Jan Hudec; 01.02.2014
comment
Привет, @JanHudec, я не согласен. ПОСТОЯННЫЙ ПОТОК - ОШИБКА! (ИМХО). Хорошего дня :) - person jrok; 01.02.2014
comment
@jrok: Очевидно, что не имеет смысла иметь постоянный поток, но когда у вас есть постоянный поток, он не должен позволять вам получать неконстантный указатель на его буфер. - person Jan Hudec; 01.02.2014

std::getline() (а также другие функции ввода-вывода) устанавливают базовое состояние потока для указания на ошибки во время синтаксического анализа или форматирования. Вот почему потоки не могут быть квалифицированы const. Более того, width() потока сбрасывается после определенных операций.

person 0x499602D2    schedule 01.02.2014