[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Problema con Debian y la programación



On Tue, Oct 23, 2007 at 07:24:19PM +0200, Jonay Domingo Ruiz wrote:
> Hola lista!!
>
> Me sucede una cosa curiosa con un programa que he tenido que hacer para la 
> universidad. El programa en cuestión está escrito en ANSI C y lo compilo 
> con el gcc que viene con Debian. El problema que me surge es con las 
> funciones de C fflush y fprintf, y es que la función fflush no funciona 
> bien por alguna razón ya que no me limpia el buffer de stdin como 
> debería.

Citando a Iñigo Montoya: "I don't think that word means what you think
it means".

fflush *no* tiene por que limpiar el buffer de stdin. Su
especificación dice que

 The function fflush() forces a write of all user-space buffered data
 for the given output ...

stdin es un flujo de entrada, no de salida.

> La función es esta:
>
> int leerCadena (Tbyte cadena[MAX_CADENA+1])
> {  ...
>    fgets(cadena, MAX_CADENA+1, stdin);
>    fflush(stdin);
>    ...
> }

No hay una forma sencilla de hacer lo que estás intentando. Parte del
problema es que nada te garantiza que stdin esté conectado a un
teclado y que la forma de averiguar si sí no está estandarizada, por
lo que algo que sirva en windows no necesariamente servirá en Linux o en
algún BSD.

Una forma no muy mala de sacarle la vuelta a esto es leer lineas
completas cada vez y luego truncar sólo el pedazo que quieres. Pero
para hacer eso bien necesitas manejar la memoria de forma dinámica.

Otra forma es que investigues sobre la biblioteca ncurses.

> extern int procesarPDU (TBloqueDeDatos pdu)
> {
>    ...
>    Tbyte aImprimir[DATOS];/*se usa para procesar los datos de la PDU*/
>    ...
>    fprintf(stdout,"              %s\n", aImprimir);
>    ...
> }
>
> cuando imprime por pantalla la variable "aImprimir" me imprime más 
> caracteres de los que dicha variable puede almacenar, por ejemplo teniendo 
> en cuenta que la constante DATOS tiene valor 10; en aImprimir solo se 
> almacenan 10 caracteres, pero en algunas ocasiones imprime más de diez.

Esto no es Pascal. En C los arreglos no saben su tamaño.

El caracter de conversión 's' en las funciones *printf significa
"interpreta el argumento como (* char) e imprime la cadena que
comienza ahí y termina en el primer byte 0". Lo que te está pasando es
que a veces aImprimir tiene su 0 al final y a veces no. Cuando no
está, printf se sigue alegremente recorriendo la memoria e imprimiendo
caracteres hasta que encuentra un 0. Megabytes después, si es
necesario.

> Recurro a ustedes por que el mismo código compilado en los windows de mi 
> facultad se ejecuta perfectamente y no hace cosas "raras". 

Seguramente en windows la función que llena 'aImprimir' siempre deja
el 0 al final. Habría que verla para saber por qué. Apuesto doble
contra sencillo que lo que está pasando es que a veces te pasas del final
del buffer.

> Imagino que debe 
> de ser algún fallo que tiene mi compilador o mi Debian (que por cierto es 
> Etch) en la manera de manejar stdin y stdout.

Pues, si le llamas "fallo" a implementar la norma de C, sí, es un
fallo :D

Más en serio, lo que pasa es que estás usando comportamiento no
especificado de las funciones que, por casualidad, en tu compilador de
windows funciona como te gusta.

Instala el paquete manpages-dev, que contiene la documentación de
todas estas funciones. Una vez que lo tengas

 $ man 3 <función>

te dirá todo lo que quieras saber (y un poco más) sobre la función.

-- 
Rodrigo Gallardo
GPG-Fingerprint: 7C81 E60C 442E 8FBC D975  2F49 0199 8318 ADC9 BC28

Attachment: signature.asc
Description: Digital signature


Reply to: