sirve significado que para namespace libreria funciones c++ stl iostream

c++ - significado - ¿Cómo se almacena std:: iostream en búfer?



std::cout significado (2)

Las respuestas a las preguntas inmediatas sobre si y cómo se almacena std::istream son: sí, std::istream es un búfer que utiliza una clase derivada de std::streambuf que define el enfoque real de lectura y almacenamiento en búfer para una fuente concreta (o cuando se usa un std::ostream para un destino). Si esto realmente hace algún almacenamiento depende de esta clase concreta y su operación generalmente no puede evitarse.

Dicho esto, este no es tu problema! El problema es que normalmente la entrada no se envía a la entrada estándar si un programa hasta que se pulsa la tecla de nueva línea. Esto es para que algunas ediciones de línea puedan realizarse mediante la implementación del terminal y no tengan que hacerlo todos los programas. Desafortunadamente, no hay un enfoque portátil para cambiar esto. En POSIX, puede convertir la secuencia de entrada estándar (usando el descriptor de archivo 0 ) en modo no canónico usando tcgetattr() y tcsetattr() . No sé cómo lograr esto en sistemas que no son POSIX.

Caso de uso general

Estoy tratando de implementar un shell básico.

Descripción

Necesito leer la entrada del usuario hasta que se presionen algunos delimitadores para que se pueda realizar la acción correspondiente. Esos delimitadores pueden ser una sola ''a'', una ''b'' o una ''c''.

Un ejemplo de entrada se vería así (donde > es el indicador de comandos de la shell):

> 111-222-333-444a Ok, ''111-222-333-444'' entered

¿Por qué quiero delimitador en línea en lugar del delimitador de "nueva línea"?

Porque me gustaría escuchar eventos de teclado como ''flecha arriba'' para borrar el comando actual e imprimir el último comando (implementando una función de historial).

Porque me gustaría escuchar eventos de teclado como ''tabulación'' para completar automáticamente el comando actual (implementando la función de autocompletar).

Lo que tengo hasta ahora

Hasta ahora, mi código se ve así:

bool done = false; char c; while (!done && std::cin.get(c)) { switch (c) { case ''a'': // Do something corresponding to ''a'' done = true; break; case ''b'': // Do something corresponding to ''b'' done = true; break; case ''c'': // Do something corresponding to ''c'' done = true; break; default: // buffer input until a delimiter is pressed break; } }

Sin embargo, el bucle parece ejecutarse solo después de haber presionado la tecla ''nueva línea''. Este comportamiento mata la esencia interactiva de la entrada del usuario.

¿Cuál es la pregunta?

Sé que std :: ostream tiene un búfer, por lo que el contenido no se escribe en el disco hasta que ocurre algún evento, pero ¿qué pasa con std :: istream? ¿Está amortiguado? En caso afirmativo, ¿cómo es y cuáles son mis opciones para evitar este comportamiento?

Además, he etiquetado esta pregunta como "tarea" porque, en caso de que no sea un ejercicio escolar, es un ejercicio que estoy tratando de hacer solo y no quiero solo elegir una biblioteca que implemente todo esto.


Si se encuentra en un sistema operativo POSIX, puede configurar el terminal para que no se almacene utilizando las funciones y estructuras declaradas en termios.h . Básicamente, debe deshabilitar la entrada canónica y configurar el terminal para el modo no canónico. Estos son algunos enlaces que pueden ayudarlo a comprender la diferencia entre los dos modos de terminal:

  1. Entrada no canónica (del manual libc)

    En el modo de entrada no canónica , los caracteres de edición especiales como ERASE y KILL se ignoran. Las facilidades del sistema para que el usuario pueda editar la entrada se deshabilitan en modo no canónico, de modo que todos los caracteres de entrada (a menos que sean especiales para propósitos de control de señal o flujo) se pasen al programa de aplicación exactamente como se escribió. Es responsabilidad del programa de aplicación proporcionarle al usuario formas de editar la entrada, si corresponde.

  2. Entrada de terminal canónica vs. no canónica

    Para entrada canónica - piense shell; en realidad, piense bien en la antigua carcasa de Bourne, ya que Bash y sus familiares tienen edición de línea de comandos. Usted escribe una línea de entrada; si comete un error, use el carácter de borrado (el valor predeterminado es retroceder, generalmente; a veces, DEL) para borrar el carácter anterior ... Para entradas no canónicas : piense en vi o vim o ... presione un carácter, y Está inmediatamente disponible para el programa. No te detendrás hasta que pulses regresar.

  3. Descripción de la interfaz de terminal

    Este capítulo describe una interfaz de terminal general que se proporciona para controlar los puertos de comunicaciones asíncronos. Depende de la implementación, ya sea que admita conexiones de red, puertos síncronos o ambos.

Sin embargo, en esencia, el problema con el que se está encontrando no es con la interfaz iostream de C ++, sino que tiene que ver con la forma en que se configuró el terminal de control del que está leyendo la interfaz iostream de C ++. Por lo tanto, aprovechar las ventajas de la E / S no almacenada dependerá de la plataforma y dependerá de si utiliza Windows o una plataforma compatible con POSIX real (esto incluye los entornos POSIX para Windows como Cygwin).

Si descubre que la confusión con la configuración del terminal es demasiado problemática, también puede buscar en una biblioteca de programación de curses multiplataforma, como PDCurses que abstraerá la mayoría de las complejidades de los tipos de terminales subyacentes.