2015-01-13 15 views
4

У меня есть этот простой код, чтобы принять 3-х символов ,:Почему tcflush не работает для scanf?

char a,b,c; 
scanf("%c",&a); 
scanf("%c",&b); 
scanf("%c",&c); 
printf("%c",a); 
printf("%c",b); 
printf("%c",c); 

Я понимаю, почему это будет принимать только 2 символа, потому что второй зсапЕ принимает возврат каретки. Однако, если при использовании __fpurge(stdin); между каждым сканированием код работает, как ожидалось. Но если я использую read(STDIN_FILENO,&a,1); вместо scanf, это не сработает. Для read() работает только tcflush(STDIN_FILENO,TCIOFLUSH);, но он не работает с scanf. Может кто-нибудь объяснить мне, почему?

+3

Вы уверены, что вызвали '__fpurge (STDIN_FILENO);' или это было '__fpurge (stdin);'? –

ответ

6

fpurge опустошает буфер на уровне C, который является уровнем, на котором работает scanf.

tcflush делает это на более низком уровне (системном уровне), на котором уровень read работает.

scanfread для заполнения своего буфера.

Итак, в первом случае: освобождение C-буфера с помощью scanf работает хорошо, но ничего не делает на системном уровне.

Во втором случае опорожнения системы-буфер, конечно, работает с read, но не с scanf потому что при использовании scanf, данные по крайней мере, до возврата каретки уже присутствуют в C-буфере. Первые scanf читают множество данных, помещают их в буфер и затем используют этот буфер, чтобы вернуть вам только один символ. Затем вы tcflush, который сбрасывает буфер системного уровня, но ничего не делает для C-буфера, поэтому следующий scanf способен найти в нем возврат каретки.

+0

Не могли бы вы объяснить мне, как буфер уровня C и буфер уровня системы связаны простым примером? –

+2

Когда вы используете данные 'fread', данные считываются из C-буфера. Если этот пуст, то он перезаправляется из системы с помощью 'read'. Когда данные 'fwrite' записываются в C-буфер. Если он заполнен, данные очищаются системой, используя 'write'. Просто подумайте о том, как вы управляете долларами в кармане против вашего банковского счета (карман = c-buffer, bank = system; карманный полный флеш для банка, пустой карман, заполнение из банка) ... –

+0

Это прояснилось! Благодаря! –