2016-05-04 3 views
2

мне нужно, чтобы попытаться заглянуть несколько символов из std::istream (который может быть std::cin), так что я написал простой цикл, чтобы позвонить get() много раз, а затем putback() много раз:PEEK несколько символов из CIN с Putback

std::vector<char> peek_many(std::istream& is, int N) { 
    std::vector<char> data; 
    data.reserve(N); 

    for (int i = 0; i < N; ++i) { 
     data.push_back(is.get()); 
    } 

    for (int i = 0; i < N; ++i) { 
     is.putback(data[N-i-1]); 
    } 

    return data; 
} 

Гарантировано, что оно будет работать на всех istream s (независимо от того, читаю ли я файл, cin, istringstream и т. Д.)? Если нет, почему бы и нет?

+0

'std :: istringstream' вводится только, его можно читать только, вы не можете в него вставлять' putback() 'данные. –

+1

Отключить тему, не лучше ли было бы вернуть более короткий вектор, если бы было достигнуто 'EOF', вместо того, чтобы возвращать вектор с завершающим' EOF '? – LogicStuff

+0

@Remy Требуется ссылка –

ответ

1

putback вызывает sputback, который работает только в том случае, если имеется позиция возврата. Ничто не гарантирует, что существует неопределенное количество таких позиций.

+0

Как я могу узнать, сколько позиций доступно? – Barry

+0

Когда 'sputback' возвращает' EOF', вы выбежали ;-) Или вы можете посмотреть 'gptr()' vs 'eback()', что дает вам нижнюю границу. –

+0

Это «защищенные». – Barry

1

Можно только предположить, что 1 символ «широкий» положил буфер. Вам нужно будет добавить дополнительный слой абстракции, чтобы предоставить больше места для возврата.

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

+0

Как выглядит такая абстракция? – Barry

+2

Дополнительный уровень буферизации в вашем коде. Вы читаете данные из потока в свой собственный буфер достаточного размера, а затем вы можете читать/просматривать данные из буфера по мере необходимости, не пытаясь вернуть данные в поток. –

+0

Или вы можете вызвать '[pub] setbuf', чтобы сообщить' streambuf', что вы хотите больший буфер, за исключением того, что, к сожалению, вообще не имеет никакого полезного четкого поведения. –