Cómo obtener el carácter por última vez que ungetc vuelve a poner en un ARCHIVO *

Supongamos que tengo un FILE* creado por fopencookie , ¿qué sucede si llamo a ungetc en el FILE* ? Supongamos que he puesto setvbuf en el FILE* como _IONBF para hacerlo sin búfer. Parece que el fopencookie no admite un controlador para ungetc .

El fondo es que quiero ejecutar scanf en istream , vea scanf en un objeto istream . Una sugerencia es usar fopencookie y estaba tratando de envolver istream como FILE * por fopencookie , el problema surge, necesito asegurarme de que FILE* no almacena nada, sin embargo, scanf leerá al menos un carácter cuando los campos de análisis cuyo ancho es desconocido, por ejemplo, para% d continuará leyendo hasta que encuentre el espacio o el final de línea. Supongo que scanf devolverá el carácter al FILE* de ungetc , en cuyo caso también necesito devolverlo al istream . ¿Es posible saber qué personaje escanea se desmarca? Gracias.

fopencookie es una extensión de GNU que, por lo que sé, no existe en ninguna otra biblioteca de C.

La implementación de la stdio GNU libc de stdio es decididamente más stdio de lo que debería ser debido a un antiguo bash (pre-EGCS, si es que significa algo para usted) de hacer que los objetos FILE puedan usar directamente como objetos C ++ streambuf . ¡No se engañe! – pero la respuesta a su pregunta puede encontrarse aquí: https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/genops.c#l722 (la implementación de ungetc se llama _IO_sputbackc es uno de los vestigios restantes de ese antiguo bash) Citaré el código, es breve:

 722 int 723 _IO_sputbackc (fp, c) 724 _IO_FILE *fp; 725 int c; 726 { 727 int result; 728 729 if (fp->_IO_read_ptr > fp->_IO_read_base 730 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c) 731 { 732 fp->_IO_read_ptr--; 733 result = (unsigned char) c; 734 } 735 else 736 result = _IO_PBACKFAIL (fp, c); 737 738 if (result != EOF) 739 fp->_flags &= ~_IO_EOF_SEEN; 740 741 return result; 742 } 

Lo que esto significa es que si el carácter rechazado es idéntico al que se encuentra justo detrás del puntero de lectura en el búfer del objeto FILE , simplemente disminuye el puntero de lectura una vez; de lo contrario, se llama a _IO_PBACKFAIL . Cavar un poco más en ese directorio (en particular, en libioP.h y iofopncook.c ) revela que _IO_PBACKFAIL en un FILE creado con llamadas _IO_default_pbackfail Esa función es mucho más larga y no voy a citarla asigna un “búfer de copia de seguridad” especial y guarda el carácter allí. Este búfer de respaldo puede crecer para acomodar un número arbitrario de llamadas a ungetc si es necesario.

Entonces, la respuesta a su pregunta es que no importa cuántas veces llame a ungetc en una fila (u otras funciones de la biblioteca lo hacen por usted), nunca se le pedirá a las funciones de cookies que hagan nada. Todo se maneja internamente al FILE . Por mi respuesta a tu otra pregunta, te recomiendo encarecidamente que encuentres algún otro enfoque, pero para lo que estabas tratando de hacer, no veo por qué crees que necesitas “devolver a este personaje al istream también”.