Pregunta

Empecé a leer " El lenguaje de programación C " (K & amp; R) y tengo una duda sobre la función getchar () .

Por ejemplo, este código:

#include <stdio.h>

main()
{
  int c;

  c = getchar();
  putchar(c);
  printf("\n");   
}

Al escribir toomanychars + CTRL + D (EOF) se imprime solo t . Creo que se espera ya que es el primer personaje introducido.

Pero entonces esta otra pieza de código:

#include <stdio.h>

main()
{
  int c;

  while((c = getchar()) != EOF) 
    putchar(c);
}

Al escribir toomanychars + CTRL + D (EOF) imprime toomanychars .

Mi pregunta es, ¿por qué sucede esto si solo tengo una única variable char? ¿Dónde se almacenan los demás caracteres?

EDIT:

Gracias a todos por las respuestas, comienzo a obtenerlo ahora ... solo un problema:

El primer programa sale cuando se le da CTRL + D mientras que el segundo imprime toda la cadena y luego espera más información del usuario. ¿Por qué espera otra cadena y no sale como la primera?

¿Fue útil?

Solución

Se trata la secuencia de entrada como un archivo. Es como si abrieras un archivo que contenía el texto " toomanychars " y leerlo o enviarlo de salida un carácter a la vez.

En el primer ejemplo, en ausencia de un bucle while, es como si abriera un archivo y leyera el primer carácter, y luego lo imprimiera. Sin embargo, el segundo ejemplo continuará leyendo los caracteres hasta que obtenga una señal de fin de archivo ( ctrl + D en su caso) como si estuviera leyendo un archivo en el disco.


En respuesta a su pregunta actualizada, ¿qué sistema operativo está utilizando? Lo ejecuté en mi computadora portátil con Windows XP y funcionó bien. Si presiono Intro, imprimiría lo que tenía hasta ahora, formaría una nueva línea y luego continuaría. (La función getchar () no regresa hasta que se presiona intro, que es cuando no hay nada en el búfer de entrada cuando se llama). Cuando presiono CTRL + Z (EOF en Windows), el programa termina. Tenga en cuenta que en Windows, el EOF debe estar en una línea propia para contar como un EOF en el símbolo del sistema. No sé si este comportamiento se imita en Linux o en cualquier sistema que esté ejecutando.

Otros consejos

getchar obtiene un solo carácter de la entrada estándar, que en este caso es el búfer del teclado.

En el segundo ejemplo, la función getchar está en un while que continúa hasta que encuentra un EOF , por lo que continuará en bucle y recupere un carácter (e imprima el carácter en la pantalla) hasta que la entrada quede vacía.

Las llamadas sucesivas a getchar obtendrán caracteres sucesivos que provienen de la entrada.

Ah, y no te sientas mal por hacer esta pregunta, me sorprendió la primera vez que me encontré con este problema también.

Algo aquí esta amortiguado. p.ej. el ARCHIVO stdout * en el que se escribe putchar podría ser line.buffered. Cuando el programa finalice (o se encuentre con una nueva línea), tal ARCHIVO * será fflush () 'ed y verá la salida.

En algunos casos, el terminal real que está viendo puede almacenar en búfer la salida hasta una nueva línea, o hasta que se le indique a la propia terminal que vacíe su búfer, lo que podría ser el caso cuando el programa en primer plano actual se cierre ya que quiere presentar un nuevo mensaje.

Ahora, lo que probablemente será el caso real aquí es que es la entrada que está almacenada en búfer (además de la salida :-)) Cuando presiona las teclas, aparecerá en la ventana de su terminal. Sin embargo, el terminal no enviará esos caracteres a su aplicación, los almacenará en búfer hasta que le indique que sea el final de la entrada con Ctrl + D, y posiblemente también una nueva línea. Aquí hay otra versión para jugar y reflexionar sobre: ??

int main() {
  int c;
   while((c = getchar()) != EOF) {
     if(c != '\n')
        putchar(c);
   }
    return 0;
}

Intenta alimentar tu programa con una oración y pulsa Intro. Y haz lo mismo si comentas. if (c! = '\ n') Tal vez pueda determinar si su entrada, salida o ambas están almacenadas de alguna manera. Esto se vuelve más interesante si ejecuta lo anterior como: ./mytest | ./mytest

(Como sidecomment, tenga en cuenta que CTRD + D no es un personaje, ni es EOF. Pero en algunos sistemas resultará en el cierre de la secuencia de entrada, lo que de nuevo elevará EOF a cualquiera que intente leer desde la secuencia).

Tu primer programa solo lee un carácter, lo imprime y sale. Tu segundo programa tiene un bucle. Sigue leyendo los caracteres uno por uno e imprimiéndolos hasta que lee un carácter EOF. Solo se almacena un carácter en un momento dado.

Solo está utilizando la variable c para contener cada carácter de uno en uno.

Una vez que haya mostrado el primer char ( t ) usando putchar (c) , se olvida del valor de c asignando el siguiente carácter ( o ) a la variable c , reemplazando el valor anterior ( t ).

el código es funcionalmente equivalente a

main(){
  int c;
  c = getchar();
  while(c != EOF) {
    putchar(c);
    c = getchar();
  }
}

puede que encuentres esta versión más fácil de entender. la única razón para poner la asignación en el condicional es evitar tener que escribir 'c = getchar ()' dos veces.

Para su pregunta actualizada, en el primer ejemplo, solo se lee un carácter. Nunca llega a la EOF. El programa termina porque no hay nada que hacer después de completar la instrucción printf. Sólo lee un carácter. Lo imprime Pone en una nueva línea. Y luego termina ya que no tiene nada más que hacer. No lee más de un carácter.

Mientras que, en el segundo código, getchar y putchar están presentes dentro de un bucle while. En esto, el programa sigue leyendo los caracteres uno por uno (como lo hace el bucle) hasta que alcanza el carácter EOF (^ D). En ese punto, coincide con c! = EOF y, dado que las condiciones no se cumplen, sale del bucle. Ahora no hay más sentencias para ejecutar. Así que el programa termina en este punto.

Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top