[ Foro de C ]

Conteo de caracteres

29-May-2014 04:18
Andrew Pollard
3 Respuestas

Estoy estudiando C con el libro "The C Programming Language", la segunda edición especificamente. Y alli se encuentra un ejercicio para contar los caracteres, y lo he copiado exactamente igual en el IDE (CodeBlocks), pero no funciona como lo dice el libro. Por qué?

En este enlace se encuenrtra el código:
http://paste.ubuntu.com/7540567/

Quizás por los cambios que se han realizado en el estandar C11 ??
Si es así no se donde conseguir la información de este último estandar. He buscado sin éxito.


29-May-2014 11:30
Nacho Cabanes (+31)

Por partes...

1) Puedes "copiar y pegar" el fuente aquí, se verá bien:

 
#include <stdio.h>
 
/*Character Counting*/
 
main()
{
    long nc;
 
    nc = 0;
    while(getchar() != EOF)
        ++nc;
    printf("%ld\n", nc);
}
 



2) Mi curso de C (en su versión PDF) sí habla de la mayoría de cambios "importantes" de C99 y C11. Lo puedes encontrar en

http://www.nachocabanes.com/c/

3) Esos cambios afectan a cosas como "gets", pero no a "getchar". El (primer) problema de tu programa es que "main" no devuelve nada. Desde C99, se debería devolver un valor (típicamente, "main" será un "int", y el valor devuelto será 0 si no ha habido problemas).

4) Aun así, la muchas versiones de CodeBlocks son pre-C99, así que me extraña que te dé ese problema. Deberías tener un warning, no un error de compilación.   El fuente "correcto" (pero con problemas que te comento más adelante) sería

 
#include <stdio.h>
 
/*Character Counting*/
 
int main()
{
    long nc;
 
    nc = 0;
    while(getchar() != EOF)
        ++nc;
    printf("%ld\n", nc);
    return 0;
}
 




5) En mi equipo de pruebas (un Linux Mint 16, con GCC 4.8.1, del año 2013) tu programa original compila correctamente (con un "warning", insisto) y se ejecuta, aunque (segundo problema) no termina nunca, porque desde teclado no obtendrás un EOF (End of File) cuando lees con "getchar". En mi caso, cuenta realmente las letras si leo desde fichero, haciendo

 
./gchar < gchar.c
 


(como podrás intuir, "gchar.c" es el fuente de tu ejemplo, y "gchar" es el ejecutable). La respuesta que obtengo en pantalla es "148", que, como era de esperar, coincide con el tamaño en bytes del fichero fuente.


29-May-2014 22:30
Andrew Pollard

* Gracias por darme referencia a tu curso que contiene información sobre C99 y C11. En cuanto a los estandars me doy cuenta que el libro que estoy estudiando fue escrito aproximadmente en 1988, y su contenido está enfocado en el estandar C89, que sería el primero, luego vienen el C90, luego el C99 y el C11. Y gracias también por los detalles que se debe colocar "int" antes de "main" y "return 0" como última instrucción de "main".

* Para aclarar, el único problema que me daba el código en CODEBLOCKS es que el bucle nunca termina ciertamente como dices. Me di cuenta de esto colocando un "printf" como última instrucción del bucle y al leer tu respuesta. Ciertamente el "getchar" al no recibir un caracter como entrada nunca retorna un EOF, con un simple ENTER tampoco genera un EOF, cosa que en el libro dice que si, que usando el teclado como entrada, el "getchar" al no recibir entrada genera un EOF. Me gustaría saber por qué esto no esta ocurriendo? Será por el sistema operativo que usaba el autor del libro si generaba EOF? Será que el sistema operativo que yo uso (MS WINDOWS 7) no genera un EOF al darle ENTER?

* Investigando en internet encontré que si le doy ctrl + z y luego le doy ENTER si genera un EOF y el bucle termina y me da el resultado pero esa última entrada la cuenta también como un caracter más. Así que que con solo modificar el valor de la inicialización de "while" llamado "nc" de "0" a "-1", luego de introducir ctrl + z sale del bucle y da como resultado la cantidad correcta de caracteres que contiene la palabra anteriormente introducida. Por lo tanto esta es otra solución al problema aparte de tu solción. Qué opinas?

 
#include <stdio.h>
/*Character Counting*/
main()
{
    long nc;
 
    nc = -1;
    while(getchar() != EOF)
        ++nc;
    printf("%ld\n", nc);
}
 



30-May-2014 19:34
Nacho Cabanes (+31)

Que yo sepa, cuando lees de teclado, nunca vas a tener un EOF si se pulsa Intro, porque la tecla Intro tiene asociado el código ASCII 13, que es el que se devolverá.

El "while" seguirá, y "getchar" esperará que pulses otraa tecla. Sólo te devolverá EOF "de forma natural" si rediriges la entrada desde un fichero, que sí tendrá un "fin de fichero" claro, o si tú "tecleas" ese carácter EOF  (pulsando Ctrl+Z, algo que no es intuitivo para el usuario de tu programa).

Tu solución es correcta, aunque me sorprende (sin probarlo) que te cuente ese carácter de control, porque no debería entrarse al "while" en ese caso. ¿Si tecleas "hola" te cuenta 5 letras o sólo te cuenta de más cuando escribes varias frases separadas por un Intro? Porque la pulsación de Intro sí puede corresponder a dos caracteres distintos en Windows (una de tantas incompatibilidades entre sistemas que C deja para que seas tú, como programador, quien la solucione).







(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)