2013-05-21 8 views
6

Поскольку я обнаружил fflush(stdin) не является переносимым способом справиться со знакомой проблемой «новой строки скрываясь во входном буфере», я использую следующее, когда я должен использования scanf:Может ли fseek (stdin, 1, SEEK_SET) или перемотка назад (stdin) использоваться для сброса входного буфера вместо не-портативного fflush (stdin)?

while((c = getchar()) != '\n' && c != EOF); 

Но сегодня я наткнулся на эту линию, которую я отметил от cplusplus.com on fflush:

fflush() ... в открытых файлах для обновления (т.е. открыты для чтения и сочинительства), поток должен быть очищен Afte Перед выполнением операции ввода выполните операцию вывода. Это может быть сделано либо путем перестановки (FSEEK, fsetpos, перемотка назад) или позвонив по телефону явно fflush

На самом деле, я прочитал, что перед многими times.So я хочу, чтобы подтвердить, если я могу просто использовать любой из следующих перед scanf() служить той же цели, что fflush(stdin) служит, когда она поддерживается:

fseek(stdin,1,SEEK_SET); 
rewind(stdin); 

PSrewind(stdin) кажется довольно безопасным и работоспособным, чтобы очистить буфер, я не прав?

Ошибка Я хотел бы упомянуть fseek(stdin,0,SEEK_SET), если мы говорим о stdin, как мы не можем использовать любое смещение, отличное от 0 или один возвращенного ftell() в этом случае.

+0

Из вашей цитаты,»... * поток должен быть промыт после операции вывода * .. . ". Ожидаете ли вы выполнять выходные операции на 'stdin', чтобы требовать' fflush (stdin) '? Это кажется глупым! Вы хотите * писать * в поток * только для чтения * Почему бы вам не описать, что вы подразумеваете под * flush buffer *, или то, что вам нужно, 'fflush (stdin)' делать? Вы также можете подумать о том, что на самом деле делает 'fflush' в соответствии с [инструкцией, отличной от C++] (http://pubs.opengroup.org/onlinepubs/009695399/functions/fflush.html). В конце концов, это C, а не C++ ... – Sebivor

+0

@undefinedbehaviour Это не моя цитата. Это взято из http://www.cplusplus.com/reference/cstdio/fflush/, и это говорит о потоках ввода-вывода, а не о 'stdin' в частности. Я имел в виду, что при чтении из' stdin', в соответствии с этим параграфом, мы могли бы его очистить, используя 'rewind()' или 'fseek()' на нем. – Jugni

+0

'stdin' открыт только для чтения, а не для обновления (как для чтения, так и для записи). Не путайте эти два режима. Это не редкость для того, чтобы этот сайт был грубым неточным. Найдите другой сайт руководства. Я рекомендую opengroup. – Sebivor

ответ

3

Это единственная портативная идиома использовать:

while((c = getchar()) != '\n' && c != EOF); 

Нескольких нитей, включая this объяснить, почему feesk обычно не работает. по тем же причинам я сомневаюсь, что rewind будет работать либо на самом деле страница человек говорит, что это эквивалентно:

(void) fseek(stream, 0L, SEEK_SET) 
+0

Я прочитал эту ссылку, которую вы дали. Но это кажется немного трудным для понимания. Можете ли вы поместить часть этой ссылки, которая имеет отношение к этому вопросу, в нескольких простых строках? – Jugni

+0

@Jugni Этот комментарий действительно объясняет это хорошо http://stackoverflow.com/questions/4917801/using-fseek-with-a-file-pointer-that-points-to-stdin#comment5479013_4917849 В основном поток не хранится нигде. Если вы хотите искать данные, прочитайте их в памяти. –

+0

Но я прочитал поток буферизирован по умолчанию. Я уверен, что 'stdin'and' stdout' буферизованы. Как все потоки открываются с помощью 'fopen()' – Jugni