2014-01-31 6 views
2

Базовый вопрос здесь, я пытаюсь изучить основную часть iostream.Почему getline() не принимает константу istream?

Мне говорят, что строятся линии считывания функции const istream &. т.е. validateFile (Const IStream & есть)

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

Возможно ли получить информацию из постоянного потока?

+2

Он читает строку из потока, поэтому он меняет свое состояние. – juanchopanza

ответ

5

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

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

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

+1

Какой внутренний указатель вы имеете в виду? –

+1

@MemyselfandI Вы правы, istream - это просто интерфейс и использует ли поток фактических файлов какой-либо перегиб указателя на его буфер или нет, это деталь реализации. – atablash

2

Можно получить данные из потока 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; 
} 
+0

Это должно рассматриваться как ** ОШИБКА В СПЕЦИФИКАЦИИ **. -1, чтобы противостоять глупым upvotes. –

+0

Привет, @JanHudec, я не согласен. Это ОШИБКА, КОТОРЫЙ ИМЕЕТ КОНСТРУКЦИЮ! (ИМХО). Хороший день :) – jrok

+0

@jrok: Очевидно, нет смысла иметь поток const, но когда у вас есть поток const, он не должен позволять вам получать неконстантный указатель на его буфер. –

0

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