que - getche c++
Confusión acerca de cómo funciona un bucle de getchar() internamente (1)
He incluido un programa de ejemplo usando getchar()
continuación, como referencia (no es probable que alguien lo necesite), y siéntase libre de abordar sus inquietudes si lo desea. Pero mi pregunta es:
¿Qué está sucediendo exactamente cuando el programa llama a getchar()
?
Aquí está mi entendimiento (por favor aclararme o corregirme):
- Cuando se llama a getchar, verifica el buffer de STDIN para ver si hay alguna entrada.
- Si no hay ninguna entrada, getchar duerme.
- Después de despertar, comprueba si hay alguna entrada y, si no lo hace, se pone a dormir otra vez.
- Los pasos 2 y 3 se repiten hasta que haya entrada.
- Una vez que hay una entrada (que por convención incluye un ''EOF'' al final), getchar devuelve el primer carácter de esta entrada y hace algo para indicar que la siguiente llamada a getchar debería devolver la segunda letra del mismo buffer. No estoy realmente seguro de qué es eso.
- Cuando no quedan más caracteres que EOF, ¿getchar vaciar el búfer?
Los términos que utilicé probablemente no sean del todo correctos.
#include <stdio.h>
int getLine(char buffer[], int maxChars);
#define MAX_LINE_LENGTH 80
int main(void){
char line[MAX_LINE_LENGTH];
int errorCode;
errorCode = getLine(line, sizeof(line));
if(errorCode == 1)
printf("Input exceeded maximum line length of %d characters./n", MAX_LINE_LENGTH);
printf("%s/n", line);
return 0;
}
int getLine(char buffer[], int maxChars){
int c, i = 0;
while((c = getchar()) != EOF && c != ''/n'' && i < maxChars - 1)
buffer[i++] = c;
buffer[i++] = ''/0'';
if(i == maxChars)
return 1;
else
return 0;
}
Los pasos 2-4 están ligeramente apagados.
Si no hay entrada en el búfer de E / S estándar, getchar()
llama a una función para volver a cargar el búfer. En un sistema tipo Unix, eso normalmente termina llamando a la llamada al sistema read()
, y la llamada al sistema read()
pone el proceso en reposo hasta que haya entrada para procesar, o el núcleo sabe que no habrá entrada para ser procesado (EOF). Cuando vuelve la lectura, el código ajusta las estructuras de datos para que getchar()
sepa la cantidad de datos disponibles. Tu descripción implica sondeo; el sistema de E / S estándar no sondea para la entrada.
El paso 5 usa los punteros ajustados para devolver los valores correctos.
Realmente no hay un personaje EOF; es un estado, no un personaje. Aunque escribe Control-D o Control-Z para indicar "EOF", ese carácter no se inserta en la secuencia de entrada. De hecho, esos caracteres hacen que el sistema elimine cualquier tipo de caracteres que todavía estén esperando operaciones de "edición de línea" (como el retroceso) para cambiarlos de modo que estén disponibles para la llamada al sistema read()
. Si no hay tales caracteres, entonces read()
devuelve 0 como el número de caracteres disponibles, lo que significa EOF. Entonces getchar()
devuelve el valor EOF
(por lo general -1
pero se garantiza que es negativo, mientras que los caracteres válidos se garantiza que no sean negativos (cero o positivo)).
Entonces, básicamente, en lugar de sondear, ¿es que al tocar Return devuelve una cierta interrupción de E / S, y cuando el sistema operativo recibe esto, se activan los procesos que están inactivos para E / S?
Sí, presionar Retorno dispara interrupciones y el kernel del sistema operativo los procesa y despierta los procesos que están esperando los datos. El kernel despierta el controlador de la terminal cuando se produce la interrupción y decide qué hacer con los caracteres que acaban de recibir. Pueden esconderse para su posterior procesamiento (modo canónico) o ponerse a disposición de inmediato (modo raw), etc. Suponiendo, por supuesto, que la entrada sea una terminal; si la entrada proviene de un archivo de disco, es más simple en muchos sentidos, o si se trata de un conducto, o ...
Nominalmente, no es la aplicación de terminal la que se despierta por la interrupción; es el kernel el que se despierta primero, luego el shell que se ejecuta en la aplicación de la terminal que se despierta porque hay datos para leer, y solo cuando hay salida la aplicación del terminal se activa.
Digo "nominalmente" porque existe la posibilidad de que la aplicación de terminal medie la E / S a través de pty (pseudo-tty), pero creo que ocurre en el kernel y la aplicación del terminal está involucrada bastante tarde en el proceso. En realidad, existe una gran desconexión entre el teclado donde escribe y la pantalla donde aparece lo que escribe.
Consulte también Entrada de terminal canónica versus no canónica .