• Miércoles 8 de Mayo de 2024, 00:11

Autor Tema:  señal EOF  (Leído 2213 veces)

nachete222

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
señal EOF
« en: Jueves 4 de Septiembre de 2008, 04:13 »
0
Hola,

Estoy empezando con unos programas muy basicos en C, tengo uno que supuestamente realiza un conteo de caracteres
el programa es este:

Citar
#include <stdio.h>

/* count lines in imput,2º version */
main()
{

   double nc;

   for (nc = 0; getchar() != EOF; ++nc)
            ;
   printf("%.0fn", nc);
}

lo he compilado sin problemas, pero no consigo que llegue al final e imprima los caracteres que ha contado
la pregunta es ¿como consigo la señal EOF en una consola de linux para que el programa salga del bucle
y que imprima el resultado?

gracias de antemano

chuidiang

  • Miembro MUY activo
  • ***
  • Mensajes: 123
  • Nacionalidad: es
    • Ver Perfil
    • http://www.chuidiang.com
Re: señal EOF
« Respuesta #1 en: Jueves 4 de Septiembre de 2008, 05:29 »
0
Hola:

Normalmente la stdin no tiene EOF, siempre puedes seguir escribiendo letras. De todas formas, prueba pulsando Ctrl-z a ver qué pasa.

Se bueno.

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: señal EOF
« Respuesta #2 en: Jueves 4 de Septiembre de 2008, 08:34 »
0
EOF no es char, es int, por lo tanto jamás podrá corresponder a una tecla del teclado. Te aconsejo que la cambies por "n" o algo similar que pueda provenir del teclado (suponiendo claro que stdin apunte al teclado).

Citar
prueba pulsando Ctrl-z

Eso deja inactiva la tarea y la pasa a segundo plano en Linux. Es una señal al proceso, por tanto no te va a servir de nada (man jobs para más información).

nachete222

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
Re: señal EOF
« Respuesta #3 en: Viernes 5 de Septiembre de 2008, 17:03 »
0
Citar
Citado por: chuidiang
Normalmente la stdin no tiene EOF

En linux, con las ultimas versiones de GCC al menos, si. Aunque aun no entiendo muy bien como funciona, se supone que es para los arachivos, para detectar el final de estos (EOF= End Of File) y tiene un valor numerico equivalente a -1 esta definido en el stdio.h, si no fuese así daria un error al compilar.

Citar
Citado por: m0skit0
EOF no es char, es int, por lo tanto jamás podrá corresponder a una tecla del teclado.

algo me estaba temiendo ya, aunque solo sea por que había tocado ya todas las teclas incluso en conbinaciones de hasta 10 dedos, (ya estaba a punto de intentar añadir los de los pies)

Efectivamente parando el proceso (yo lo hacia con control+c ) se sale en mitad del bucle y no impime los resultados

Este ejemplo viene en un libro que estoy siguiendo, habla de Ansi C de Kernighan y Ritchie y no se que gaitas pero suena a antiguo, es posible que no se escriba ya de esa forma ??

Gracias a ambos por las respuestas,
Un saludo

chuidiang

  • Miembro MUY activo
  • ***
  • Mensajes: 123
  • Nacionalidad: es
    • Ver Perfil
    • http://www.chuidiang.com
Re: señal EOF
« Respuesta #4 en: Viernes 5 de Septiembre de 2008, 17:20 »
0
Hola:

Hay programas que cuando piden varias líneas por el teclado usan el Ctrl-Z o el Ctrl-D para marcar el fin de texto y terminar la entrada de datos. Por ejemplo, sendmail usa Ctrl-Z y telnet usa Ctrl-D. Por eso te comenté lo de probar con Ctrl-Z. Buscando por google, he visto que muchos sistemas linux/unix interpretan Ctrl-D como EOF, así que quizás sea mejor opción. Ojo, esto sólo vale cuando el programa está pidiendo datos por teclado. Si no está pidiendo nada, posiblemente Ctrl-Z tenga el comportamiento que indica m0skit0.

En cuanto a que el stdin lea letras o números, no es totalmente correcto. Por la stdin, hagas lo que hagas, llegan bytes, luego es el programa C el que los almacena como int o como char. Si escribes una A, al programa C le llega un byte de valor 65, que es el correspondiente al ascii de la A. Si lo metes en un int es un 65 y si lo metes en un char es una 'A'. Si le das a la flecha o a un Ctrl-algo, si nadie lo interpreta, también le llegan bytes al programa. Normalmente estas teclas raras o combinaciones suelen ser uno o dos bytes. En caso de que sean dos, el primero suele ser un ascii <ESC> que corresponde a un 27 y luego otro valor correspondiente a la otra tecla. Por ejemplo, los Ctrl-Letra suelen ser al byte de la letra siendo A el 1, B el 2, C el 3, etc. Por ejemplo Ctrl-G es un beep y es un byte 7. Un retorno de carro (Ctrl-M) es un 13. Y de hecho, getchar() devuelve un int, que será 65 si es una A, 4 si es un Ctrl-D o un 26 si es Ctrl-Z.

En cualquier caso, no creo que el Ctrl-D llegue como un EOF tal cual está escrito en el código C (dices que es un -1). Ahí m0skit0 tiene razón y quizás la mejor forma sea leer hasta que llegue un caracter concreto, por ejemplo, el correspondiente a un byte 4 que es el del Ctrl-D. No es buena idea lo del /n porque entonces sólo podrías escribir una línea, salvo que pongas como criterio terminar la entrada de datos cuando lees una línea en blanco (es decir, dos /n seguidos, el de la línea anterior y el siguiente). En el caso de Ctrl-D, por ejemplo, puedes probar

for (nc = 0; getchar()!=4; ++nc);

Se bueno.

nachete222

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
Re: señal EOF
« Respuesta #5 en: Viernes 5 de Septiembre de 2008, 17:30 »
0
Citar
Citado por m0skit0
Te aconsejo que la cambies por "n"

Hombre asi si, esto ya es otra cosa  :D

El programa al final queda asi:

#include <stdio.h>
/* count lines in imput,2º version */
main()
{
double nc;
for (nc = 0; getchar() != 'n'; ++nc)
;
printf("%.0fn", nc);
}

Salida de Terminal:
[n@localhost Programacion]$ gcc -o CuentaCaracteres CuentaCaracteres.c
[n@localhost Programacion]$ ./CuentaCaracteres
prueba de conteo de caracteres
31
[n@localhost Programacion]$

nachete222

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
Re: señal EOF
« Respuesta #6 en: Viernes 5 de Septiembre de 2008, 17:37 »
0
Gracias por la aportacion chuidiang

Efectivamente lo de 'n' solo me da de margen una linea
muy buena idea lo de que sean dos nn, me lo apunto y lo probaré

Gracias de nuevo

Editado:
Ctrl+D  También funciona con la primera versión (parece ser que así si llega la señal EOF)