c - ¿Hay alguna manera de mirar el búfer stdin?
buffer peek (3)
Sabemos que la stdin
es, de forma predeterminada, una entrada con buffer; la prueba de ello es el uso de cualquiera de los mecanismos que "dejan datos" en la stdin
, como scanf()
:
int main()
{
char c[10] = {''/0''};
scanf("%9s", c);
printf("%s, and left is: %d/n", c, getchar());
return 0;
}
./a.out
Hola
hola, y la izquierda es 10
10
siendo nueva línea, por supuesto ...
Siempre he tenido curiosidad, ¿hay alguna forma de "echar un vistazo" al búfer stdin
sin eliminar lo que pueda haber allí?
EDITAR
Un mejor ejemplo podría ser:
scanf("%9[^.]", c);
Con una entrada de "at.ct", ahora tengo "data" ( ct/n
) en stdin
, no solo una nueva línea.
Además, puede obtener el siguiente carácter en el flujo de entrada con getchar()
y luego presionarlo con ungetc()
, lo que da como resultado un estado como si el personaje no se eliminara del flujo.
La función
ungetc
empuja el carácter especificado porc
(convertido a ununsigned char
) en el flujo de entrada apuntado por flujo. Los caracteres rechazados serán devueltos por lecturas subsiguientes en ese flujo en el orden inverso al de su empuje.
El estándar garantiza solo un carácter de retroceso, pero, por lo general, puede retroceder más.
Como se menciona en las otras respuestas resp. los comentarios allí, en la práctica, es casi seguro que puedes echar un vistazo al búfer si proporcionas tu propio búfer con setvbuf
, aunque eso no está exento de problemas:
Si
buf
no es un puntero nulo, la matriz a la que apunta puede usarse en lugar de un búfer asignado por la funciónsetvbuf
eso deja la posibilidad de que el búfer provisto no se pueda usar en absoluto.
Los contenidos de la matriz en cualquier momento son indeterminados.
eso significa que no tiene garantía de que el contenido del búfer refleje la entrada real (y hace que el uso del búfer no esté definido si tiene una duración de almacenamiento automática, si somos exigentes).
Sin embargo, en la práctica, el problema principal sería averiguar dónde en la memoria intermedia comienza la parte no consumida de la entrada almacenada y dónde termina.
Puedes establecer tu propio búfer con setvbuf
en stdin, y echar un vistazo allí cuando quieras.
Si desea ver el búfer stdin
sin cambiarlo, puede decirle que use otro búfer con setbuf
, usando una matriz a la que puede acceder:
char buffer[BUFSIZ];
if (setbuf(stdin, buffer) != 0)
// error
getchar();
printf("%15s/n", buffer);
Esto te permite ver algo más que ungetc
, pero no creo que puedas ir más allá de manera portátil.
En realidad, esto es legal pero no es correcto para el estándar, citando sobre el setvbuf
( setbuf
tiene el mismo comportamiento):
Los contenidos de la matriz en cualquier momento son indeterminados.
Por lo tanto, esto no es lo que necesita si está buscando una portabilidad completa y un cumplimiento de estándares, pero no puedo imaginar por qué el búfer no debe contener lo que se espera. Sin embargo, parece funcionar en mi computadora.
Tenga en cuenta que debe proporcionar una matriz de al menos BUFSIZ
caracteres a setbuf
, y no debe realizar ninguna operación de E / S en el flujo anterior. Si necesita más flexibilidad, eche un vistazo a setbuf .