Re: problema con scanf (novato)
Ramiro Aceves wrote: segmentation fault escribió: Bueno la versión que mandé antes me parece que tenía comentarios de más, esta es la buena: #include stdio.h #include stdio_ext.h #include unistd.h #include stdlib.h int N; int a; float dato; char buffer; char respuesta1,respuesta2,respuesta3; int main(void){ printf(mete un float\n); scanf(%f,dato); __fpurge(stdin); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1 = getchar(); __fpurge(stdin); respuesta2 = getchar(); __fpurge(stdin); respuesta3=getchar(); __fpurge(stdin); printf(caracter1: %c caracter2: %c caracter3: %c\n,\ respuesta1,respuesta2,respuesta3); exit(0); } Estupendo, muchas gracias, esta funciona perfectamente, aunque hay que darle de comer más cabeceras.. :-) He buscado lo del __fpurge en el glibc-doc en html y sí que viene (ayer anduve dando vueltas por ahí y no lo ví, estoy medio ciego) De todas formas, es increíble la que hay que montar para hacer una cosa tan sencilla como leer un carácter. Lo curioso es que en la página del man de getchar no dice nada de esto, y podría haber advertido de toda esta serie de problemas. En tu versión hay que dar a intro en los tres getchar(). En la original, escribir tres letras y un solo introEstoy hecho un lío. Muchas gracias. Ramiro. Vamos a ver, en la version original al poner tres getchar() seguidos se leerán los primeros tres caracteres que introduzcas por teclado. Teniendo en cuenta que el intro se considera un caracter, al introducir abcINTRO se leerá abc. Pero en el buffer de entrada seguirá quedando INTRO. Si en lugar de esto se introdujera aINTRObINTROcINTRO, lo que leerían los tres getchar sería aINTROb. En mi version, teniendo en cuenta que cada getchar() lee un sólo caracter, lo que se hace es: Introducimos por teclado los caracteres aINTRO.Entonces en el buffer de entrada tendremos aINTRO. Como cada getchar() lee un caracter, leerá el primero del buffer, es decir a. Antes de hacer el siguiente getchar() hacemos __fpurge(), con lo cual vaciamos el buffer, por lo tanto en este momento no hay nada en el buffer de entrada. Al hacer el segundo getchar(), el programa se encontrará con el buffer vacío, es decir, no tiene datos nuevos en el buffer para leer, entonces esperará a que se los introduzcas por teclado, por ejemplo bINTRO. El proceso se repite... Por otro lado, el fflush() NO vacía el buffer, NO borra los datos del buffer. Lo que hace es escribir los datos que encuentra en el buffer de entrada (memoria) en un almacenamiento persistente (disco) para evitar que se pierdan, pero los datos siguen quedando en el buffer de entrada. Espero haberte ayudado algo, el C es un lenguaje algo complicado al empezar, pero con el tiempo llega a ser apasionante y realmente muy potente. Salu2 y hasta la próxima!!! ;-)
RE: problema con scanf (novato)
Weno, Efectivamente por lo que leo en el man, __fpurge() era lo que necesitabas. Se ve que fflush() no actua en Linux como en otras plataformas. De todas formas, cuidado con la función que no es estandar. Espero haberte ayudado algo, el C es un lenguaje algo complicado al empezar, pero con el tiempo llega a ser apasionante y realmente muy potente. Totalmente de acuerdo con segmentation_fault ;)) Un saludo, Iñaki R. p.d: Para más adelante, cuidado con scanf y los buffers overflows
Re: problema con scanf (novato)
segmentation fault escribió: El programa original podría quedar tal que así: #include stdio.h #include stdio_ext.h #include unistd.h #include stdlib.h int N; /*Numero de elementos*/ int a; char respuesta='n'; float *longitud; int main(){ printf(number of elements? [1-100]\n); scanf(%d,N); longitud = (float*)malloc(N*sizeof(float)); while(respuesta=='n'){ printf(enter element length, starting from reflector to last director [mm]\n); for (a=0;aN;a++) { printf(element number %d : ,a); scanf(%f,(longitud+a)); } printf(You have entered:\n); for (a=0;aN;a++){ printf(element number %d : ,a); printf(%f\n,*(longitud+a)); } printf(is data correct? [y/n]\n); __fpurge(stdin); respuesta=getchar(); } exit(0); } Muchísimas gracias a todos por vuestras magníficas explicaciones. Ahora creo que lo he entendido de una vez. En especial al señor segmentation fault por el extenso escrito. A partir de ahora andaré siempre con cuidado con los búfers a la hora de leer datos. Digamos que el C está más cerca del ensamblador que del BASIC :-) . El tema de los punteros, que en un principio generaba en mí un poco de rechazo, me doy cuenta de que tiene una potencia increíble y es muy elegante. Muy elegante lo del malloc, tomaré nota. (Qué burro yo con el float longitud[100]). hala, como sobra memoria Gracias a todos, hay veces que con las páginas del manual y los libros no termina uno de tenerlo claro. Saludos. Ramiro.
Re: problema con scanf (novato)
El Miércoles, 23 de Junio de 2004 11:10, Iñaki R. escribió: || Weno, || || Efectivamente por lo que leo en el man, __fpurge() era lo que necesitabas. || Se ve que fflush() no actua en Linux como en otras plataformas. De todas || formas, cuidado con la función que no es estandar. || || Espero haberte ayudado algo, el C es un lenguaje algo complicado al || empezar, pero con el tiempo || llega a ser apasionante y realmente muy potente. || || Totalmente de acuerdo con segmentation_fault ;)) || || Un saludo, || || Iñaki R. || || p.d: Para más adelante, cuidado con scanf y los buffers overflows Vaya, interesante saber que fflush() no funciona como en ms-dos. Viene bien saberlo. Un saludo.
Re: problema con scanf (novato)
Iñaki wrote: Vaya, interesante saber que fflush() no funciona como en ms-dos. Viene bien saberlo. Un saludo. Debería ser, ms-dos no implementa fflush() de acuerdo al estándar, la función fflush() en sistemas basados en GNU es conforme el estándar ANSI C3.159-1989 (C ANSI) donde el estado de apertura del flujo no es afectado. Esto es así debido a que los sistemas operativos mal diseñados fijan a que la entrada y salida sean orientadas a línea, lo cual ocasiona que la apertura de flujo sea limpiada al escribir una nueva línea. Saludos! -- nmag only gnupg 0xA024A03F [pgp.mit.edu] GNU/Linux Registered User #312624
Re: problema con scanf (novato)
Iñaki escribió: El Miércoles, 23 de Junio de 2004 11:10, Iñaki R. escribió: || Weno, || || Efectivamente por lo que leo en el man, __fpurge() era lo que necesitabas. || Se ve que fflush() no actua en Linux como en otras plataformas. De todas || formas, cuidado con la función que no es estandar. || || Espero haberte ayudado algo, el C es un lenguaje algo complicado al || empezar, pero con el tiempo || llega a ser apasionante y realmente muy potente. || || Totalmente de acuerdo con segmentation_fault ;)) || || Un saludo, || || Iñaki R. || || p.d: Para más adelante, cuidado con scanf y los buffers overflows Vaya, interesante saber que fflush() no funciona como en ms-dos. Viene bien saberlo. Un saludo. El problema es que en los libros de C no se avisa de todos estos líosVeo que si un programa tan chorra ya no es portable, ¿que será un programa serio? :-( Por cierto, no encuentro __fpurge() en las páginas del man, sólo en el paquete glibc-doc. Saludos y gracias. Ramiro.
Re: problema con scanf (novato)
Ramiro Aceves escribió: Iñaki escribió: El Miércoles, 23 de Junio de 2004 11:10, Iñaki R. escribió: || Weno, || || Efectivamente por lo que leo en el man, __fpurge() era lo que necesitabas. || Se ve que fflush() no actua en Linux como en otras plataformas. De todas || formas, cuidado con la función que no es estandar. || || Espero haberte ayudado algo, el C es un lenguaje algo complicado al || empezar, pero con el tiempo || llega a ser apasionante y realmente muy potente. || || Totalmente de acuerdo con segmentation_fault ;)) || || Un saludo, || || Iñaki R. || || p.d: Para más adelante, cuidado con scanf y los buffers overflows Vaya, interesante saber que fflush() no funciona como en ms-dos. Viene bien saberlo. Un saludo. El problema es que en los libros de C no se avisa de todos estos líosVeo que si un programa tan chorra ya no es portable, ¿que será un programa serio? :-( Por cierto, no encuentro __fpurge() en las páginas del man, sólo en el paquete glibc-doc. Saludos y gracias. Ramiro. Ah, perdonad, acabo de actualizar las páginas del manual y ya tengo la mágina del man para __fpurge. Saludos.
Re: problema con scanf (novato)
On Wed, Jun 23, 2004 at 03:44:08PM +0200, Ramiro Aceves wrote: Iñaki escribió: El Miércoles, 23 de Junio de 2004 11:10, Iñaki R. escribió: || Weno, || || Efectivamente por lo que leo en el man, __fpurge() era lo que necesitabas. || Se ve que fflush() no actua en Linux como en otras plataformas. De todas || formas, cuidado con la función que no es estandar. || || Espero haberte ayudado algo, el C es un lenguaje algo complicado al || empezar, pero con el tiempo || llega a ser apasionante y realmente muy potente. || || Totalmente de acuerdo con segmentation_fault ;)) || || Un saludo, || || Iñaki R. || || p.d: Para más adelante, cuidado con scanf y los buffers overflows Vaya, interesante saber que fflush() no funciona como en ms-dos. Viene bien saberlo. Un saludo. El problema es que en los libros de C no se avisa de todos estos líosVeo que si un programa tan chorra ya no es portable, ¿que será un programa serio? :-( Un libro de C no tiene por que avisar de esas cosas puesto que no son parte del lenguaje. Para enterarse de esos detalles lo que hay que leer son los manuales de las bibliotecas que estes usando, especialmente la biblioteca estandar. Blu.
Re: problema con scanf (novato)
Blu escribió: On Wed, Jun 23, 2004 at 03:44:08PM +0200, Ramiro Aceves wrote: Iñaki escribió: El Miércoles, 23 de Junio de 2004 11:10, Iñaki R. escribió: || Weno, || || Efectivamente por lo que leo en el man, __fpurge() era lo que necesitabas. || Se ve que fflush() no actua en Linux como en otras plataformas. De todas || formas, cuidado con la función que no es estandar. || || Espero haberte ayudado algo, el C es un lenguaje algo complicado al || empezar, pero con el tiempo || llega a ser apasionante y realmente muy potente. || || Totalmente de acuerdo con segmentation_fault ;)) || || Un saludo, || || Iñaki R. || || p.d: Para más adelante, cuidado con scanf y los buffers overflows Vaya, interesante saber que fflush() no funciona como en ms-dos. Viene bien saberlo. Un saludo. El problema es que en los libros de C no se avisa de todos estos líosVeo que si un programa tan chorra ya no es portable, ¿que será un programa serio? :-( Un libro de C no tiene por que avisar de esas cosas puesto que no son parte del lenguaje. Para enterarse de esos detalles lo que hay que leer son los manuales de las bibliotecas que estes usando, especialmente la biblioteca estandar. Blu. Tienes razón en cierta medida. Por eso a partir de ahora me centraré en la documentación de GNU en el paquete glibc-doc, que es impresionante. Saludos.
Re: problema con scanf (novato)
De latín nada jejeje. A mi me pasaba lo mismo. Me lo dijeron en el irc creo o en algún foro y me dieron la explicación pero ahora mismo no me acuerdo. Tenía algo que ver con lo que te han dicho sobre hacer el flush y todo eso. Desde luego tiene que ver sobre la forma en que funciona internamente scanf, pero como ya te he dicho ahora mismo ni idea. Siento no poder ayudarte más :(. Saludos. Gracias, he estado investigando, y al parecer, es la instrución scanf() la que estropea la siguiente getchar(). Si corremos este programa: #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } obtenemos el resultado inesperado siguiente. Al parecer, el retorno de carro que se mete al introducir el dato en scanf(), lo toma el primer getchar(): [EMAIL PROTECTED]:~/ARCHIVOS_IMPORTANTES/NEC2linux/makenec$ ./copia.exe mete un float 3.14 has metido : 3.14 ahora los getchar abc caracter1: caracter2: a caracter3: b se me ocurrió meter un espacio en la instrucción scanf y ahora va correctamente, aunque el mensaje sale despues de meter los datos..sigo sin entender... ?¿?¿?¿? :-\ #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } [EMAIL PROTECTED]:~/ARCHIVOS_IMPORTANTES/NEC2linux/makenec$ ./copia.exe mete un float 3.14 abc has metido : 3.14 ahora los getchar caracter1: a caracter2: b caracter3: c Me han recomendado suscribirme a [EMAIL PROTECTED], a ver si allí alguien me da solución a esto. Gracias.
Re: problema con scanf (novato)
Buenas, la solución a tu problema es hacer un fflush(stdin); despues de obtener un valor numérico con scanf. La razón es que el sistema operativo almacena en un buffer las teclas pulsadas, scanf() toma el primer argumento para saber qué tipo de datos son, por lo tanto el retorno de carro no lo coge. Después cuando llamas a getchar(), ésta recibe el siguiente caracter que hay en el buffer del teclado, y como scanf ha dejado el retorno de carro pues se queda con él. En caso contrario espera la pulsación. Un saludo, Iñaki R. - Mensaje Original - De: Ramiro Aceves [EMAIL PROTECTED] Fecha: Martes, Junio 22, 2004 1:28 am Asunto: Re: problema con scanf (novato) De latín nada jejeje. A mi me pasaba lo mismo. Me lo dijeron en el irc creo o en algún foro y me dieron la explicación pero ahora mismo no me acuerdo. Tenía algo que ver con lo que te han dicho sobre hacer el flush y todo eso. Desde luego tiene que ver sobre la forma en que funciona internamente scanf, pero como ya te he dicho ahora mismo ni idea. Siento no poder ayudarte más :(. Saludos. Gracias, he estado investigando, y al parecer, es la instrución scanf()la que estropea la siguiente getchar(). Si corremos este programa: #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } obtenemos el resultado inesperado siguiente. Al parecer, el retorno de carro que se mete al introducir el dato en scanf(), lo toma el primer getchar(): [EMAIL PROTECTED]:mete un float 3.14 has metido : 3.14 ahora los getchar abc caracter1: caracter2: a caracter3: b se me ocurrió meter un espacio en la instrucción scanf y ahora va correctamente, aunque el mensaje sale despues de meter los datos..sigo sin entender... ?¿?¿?¿? :-\ #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } [EMAIL PROTECTED]: mete un float 3.14 abc has metido : 3.14 ahora los getchar caracter1: a caracter2: b caracter3: c Me han recomendado suscribirme a [EMAIL PROTECTED], a ver si allí alguien me da solución a esto. Gracias.
Re: problema con scanf (novato)
[EMAIL PROTECTED] escribió: Buenas, la solución a tu problema es hacer un fflush(stdin); despues de obtener un valor numérico con scanf. La razón es que el sistema operativo almacena en un buffer las teclas pulsadas, scanf() toma el primer argumento para saber qué tipo de datos son, por lo tanto el retorno de carro no lo coge. Después cuando llamas a getchar(), ésta recibe el siguiente caracter que hay en el buffer del teclado, y como scanf ha dejado el retorno de carro pues se queda con él. En caso contrario espera la pulsación. Un saludo, Iñaki R. - Mensaje Original - De: Ramiro Aceves [EMAIL PROTECTED] Fecha: Martes, Junio 22, 2004 1:28 am Asunto: Re: problema con scanf (novato) De latín nada jejeje. A mi me pasaba lo mismo. Me lo dijeron en el irc creo o en algún foro y me dieron la explicación pero ahora mismo no me acuerdo. Tenía algo que ver con lo que te han dicho sobre hacer el flush y todo eso. Desde luego tiene que ver sobre la forma en que funciona internamente scanf, pero como ya te he dicho ahora mismo ni idea. Siento no poder ayudarte más :(. Saludos. Gracias, he estado investigando, y al parecer, es la instrución scanf()la que estropea la siguiente getchar(). Si corremos este programa: #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } obtenemos el resultado inesperado siguiente. Al parecer, el retorno de carro que se mete al introducir el dato en scanf(), lo toma el primer getchar(): [EMAIL PROTECTED]:mete un float 3.14 has metido : 3.14 ahora los getchar abc caracter1: caracter2: a caracter3: b se me ocurrió meter un espacio en la instrucción scanf y ahora va correctamente, aunque el mensaje sale despues de meter los datos..sigo sin entender... ?¿?¿?¿? :-\ #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } [EMAIL PROTECTED]: mete un float 3.14 abc has metido : 3.14 ahora los getchar caracter1: a caracter2: b caracter3: c Me han recomendado suscribirme a [EMAIL PROTECTED], a ver si allí alguien me da solución a esto. Gracias. Bien, efectivamente, gracias, funciona al poner el fflush (stdin) después de scanf. Pero todavía tengo una pequeña duda: ¿Por qué el mensaje ahora los getchar me sale después de acabar con los tres getchar() y no antes, como está escrito en el código del programa? Gracias. Ya me voy aclarando.
Re: problema con scanf (novato)
[EMAIL PROTECTED] escribió: Buenas, la solución a tu problema es hacer un fflush(stdin); despues de obtener un valor numérico con scanf. La razón es que el sistema operativo almacena en un buffer las teclas pulsadas, scanf() toma el primer argumento para saber qué tipo de datos son, por lo tanto el retorno de carro no lo coge. Después cuando llamas a getchar(), ésta recibe el siguiente caracter que hay en el buffer del teclado, y como scanf ha dejado el retorno de carro pues se queda con él. En caso contrario espera la pulsación. Un saludo, Iñaki R. - Mensaje Original - De: Ramiro Aceves [EMAIL PROTECTED] Fecha: Martes, Junio 22, 2004 1:28 am Asunto: Re: problema con scanf (novato) De latín nada jejeje. A mi me pasaba lo mismo. Me lo dijeron en el irc creo o en algún foro y me dieron la explicación pero ahora mismo no me acuerdo. Tenía algo que ver con lo que te han dicho sobre hacer el flush y todo eso. Desde luego tiene que ver sobre la forma en que funciona internamente scanf, pero como ya te he dicho ahora mismo ni idea. Siento no poder ayudarte más :(. Saludos. Gracias, he estado investigando, y al parecer, es la instrución scanf()la que estropea la siguiente getchar(). Si corremos este programa: #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } obtenemos el resultado inesperado siguiente. Al parecer, el retorno de carro que se mete al introducir el dato en scanf(), lo toma el primer getchar(): [EMAIL PROTECTED]:mete un float 3.14 has metido : 3.14 ahora los getchar abc caracter1: caracter2: a caracter3: b se me ocurrió meter un espacio en la instrucción scanf y ahora va correctamente, aunque el mensaje sale despues de meter los datos..sigo sin entender... ?¿?¿?¿? :-\ #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } [EMAIL PROTECTED]: mete un float 3.14 abc has metido : 3.14 ahora los getchar caracter1: a caracter2: b caracter3: c Me han recomendado suscribirme a [EMAIL PROTECTED], a ver si allí alguien me da solución a esto. Gracias. Perdón, perdón, miento, no me funciona lo del fflush(stdin), creí que lo había compilado y no era así, sigue sin funcionar. Si alguien puede compilarlo en su casa, a ver si le da lo mismo. Gracias. Ramiro.
Re: problema con scanf (novato)
El Martes, 22 de Junio de 2004 15:33, Ramiro Aceves escribió: || Perdón, perdón, miento, no me funciona lo del fflush(stdin), creí que lo || había compilado y no era así, sigue sin funcionar. Si alguien puede || compilarlo en su casa, a ver si le da lo mismo. || || Gracias. || Ramiro. Hola de nuevo, Siguiendo con lo del getchar y fflush(stdin) me acabo de acordar de que aunque en teoría es la solución, a mí me ocurría lo mismo que a tí, no funcionaba. Por esa razón pasé olímpicamente del getchar y usaba getche o getch (tienes que añadir un #include, pero ahora mismo no me acuerdo de cuál). En cuanto al extraño orden en el que te salen los printf y scanf estoy alucinando viendo la salida de tu programa, ni idea, si descubres algo coméntalo porque me dejas con la mosca en la oreja, ¿¿seguro que esa salida desordenada es la correspondiente al código que la precede?? quiero decir, no te has equivocado al compilar ni nada, ¿verdad? Hasta la próxima y suerte.
Re: problema con scanf (novato)
A mi as me funciona: #include stdio.h #include stdio_ext.h #include unistd.h #include stdlib.h int N; int a; float dato; char buffer; char respuesta1,respuesta2,respuesta3; int main(void){ printf("mete un float\n"); scanf("%f",dato); __fpurge(stdin); printf("has metido : %f\n",dato); printf("ahora los getchar\n"); respuesta1 = getchar(); __fpurge(stdin); respuesta2 = getchar();//read(0,respuesta2,sizeof(char)); __fpurge(stdin); respuesta3=getchar();//read(0,respuesta3,sizeof(char)); __fpurge(stdin); printf("caracter1: %c caracter2: %c caracter3: %c\n",\ respuesta1,respuesta2,respuesta3); exit(0); } Saludos!!! ;-)
Re: problema con scanf (novato)
Bueno la versin que mand antes me parece que tena comentarios de ms, esta es la buena: #include stdio.h #include stdio_ext.h #include unistd.h #include stdlib.h int N; int a; float dato; char buffer; char respuesta1,respuesta2,respuesta3; int main(void){ printf("mete un float\n"); scanf("%f",dato); __fpurge(stdin); printf("has metido : %f\n",dato); printf("ahora los getchar\n"); respuesta1 = getchar(); __fpurge(stdin); respuesta2 = getchar(); __fpurge(stdin); respuesta3=getchar(); __fpurge(stdin); printf("caracter1: %c caracter2: %c caracter3: %c\n",\ respuesta1,respuesta2,respuesta3); exit(0); }
Re: problema con scanf (novato)
El programa original podra quedar tal que as: #include stdio.h #include stdio_ext.h #include unistd.h #include stdlib.h int N; /*Numero de elementos*/ int a; char respuesta='n'; float *longitud; int main(){ printf("number of elements? [1-100]\n"); scanf("%d",N); longitud = (float*)malloc(N*sizeof(float)); while(respuesta=='n'){ printf("enter element length, starting from reflector to last director [mm]\n"); for (a=0;aN;a++) { printf("element number %d : ",a); scanf("%f",(longitud+a)); } printf("You have entered:\n"); for (a=0;aN;a++){ printf("element number %d : ",a); printf("%f\n",*(longitud+a)); } printf("is data correct? [y/n]\n"); __fpurge(stdin); respuesta=getchar(); } exit(0); }
Re: problema con scanf (novato)
Si no haces flush(stdout) no hay garantía de que el texto salga por pantalla en el momento en el que pones el printf(), printf() tan sólo pone datos en el buffer se salida pero no se encarga de imprimirlo. Saludos. Por cierto, en la lista GNU-C[1] quizá te puedan ayudar con este y otros problemas de programación con C. [1] https://listas.hispalinux.es/mailman/listinfo/gnu-c El mar, 22-06-2004 a las 15:30, Ramiro Aceves escribió: [EMAIL PROTECTED] escribió: Buenas, la solución a tu problema es hacer un fflush(stdin); despues de obtener un valor numérico con scanf. La razón es que el sistema operativo almacena en un buffer las teclas pulsadas, scanf() toma el primer argumento para saber qué tipo de datos son, por lo tanto el retorno de carro no lo coge. Después cuando llamas a getchar(), ésta recibe el siguiente caracter que hay en el buffer del teclado, y como scanf ha dejado el retorno de carro pues se queda con él. En caso contrario espera la pulsación. Un saludo, Iñaki R. - Mensaje Original - De: Ramiro Aceves [EMAIL PROTECTED] Fecha: Martes, Junio 22, 2004 1:28 am Asunto: Re: problema con scanf (novato) De latín nada jejeje. A mi me pasaba lo mismo. Me lo dijeron en el irc creo o en algún foro y me dieron la explicación pero ahora mismo no me acuerdo. Tenía algo que ver con lo que te han dicho sobre hacer el flush y todo eso. Desde luego tiene que ver sobre la forma en que funciona internamente scanf, pero como ya te he dicho ahora mismo ni idea. Siento no poder ayudarte más :(. Saludos. Gracias, he estado investigando, y al parecer, es la instrución scanf()la que estropea la siguiente getchar(). Si corremos este programa: #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } obtenemos el resultado inesperado siguiente. Al parecer, el retorno de carro que se mete al introducir el dato en scanf(), lo toma el primer getchar(): [EMAIL PROTECTED]:mete un float 3.14 has metido : 3.14 ahora los getchar abc caracter1: caracter2: a caracter3: b se me ocurrió meter un espacio en la instrucción scanf y ahora va correctamente, aunque el mensaje sale despues de meter los datos..sigo sin entender... ?¿?¿?¿? :-\ #include stdio.h int N; int a; float dato; char respuesta1,respuesta2,respuesta3; void main(void){ printf(mete un float\n); scanf(%f,dato); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1=getchar(); respuesta2=getchar(); respuesta3=getchar(); printf(caracter1: %c caracter2: %c caracter3: %c \n,respuesta1,respuesta2,respuesta3); exit(0); } [EMAIL PROTECTED]: mete un float 3.14 abc has metido : 3.14 ahora los getchar caracter1: a caracter2: b caracter3: c Me han recomendado suscribirme a [EMAIL PROTECTED], a ver si allí alguien me da solución a esto. Gracias. Bien, efectivamente, gracias, funciona al poner el fflush (stdin) después de scanf. Pero todavía tengo una pequeña duda: ¿Por qué el mensaje ahora los getchar me sale después de acabar con los tres getchar() y no antes, como está escrito en el código del programa? Gracias. Ya me voy aclarando.
Re: problema con scanf (novato)
segmentation fault escribió: Bueno la versión que mandé antes me parece que tenía comentarios de más, esta es la buena: #include stdio.h #include stdio_ext.h #include unistd.h #include stdlib.h int N; int a; float dato; char buffer; char respuesta1,respuesta2,respuesta3; int main(void){ printf(mete un float\n); scanf(%f,dato); __fpurge(stdin); printf(has metido : %f\n,dato); printf(ahora los getchar\n); respuesta1 = getchar(); __fpurge(stdin); respuesta2 = getchar(); __fpurge(stdin); respuesta3=getchar(); __fpurge(stdin); printf(caracter1: %c caracter2: %c caracter3: %c\n,\ respuesta1,respuesta2,respuesta3); exit(0); } Estupendo, muchas gracias, esta funciona perfectamente, aunque hay que darle de comer más cabeceras.. :-) He buscado lo del __fpurge en el glibc-doc en html y sí que viene (ayer anduve dando vueltas por ahí y no lo ví, estoy medio ciego) De todas formas, es increíble la que hay que montar para hacer una cosa tan sencilla como leer un carácter. Lo curioso es que en la página del man de getchar no dice nada de esto, y podría haber advertido de toda esta serie de problemas. En tu versión hay que dar a intro en los tres getchar(). En la original, escribir tres letras y un solo introEstoy hecho un lío. Muchas gracias. Ramiro.
Re: problema con scanf (novato)
On Sun, 20 Jun 2004 16:55:32 +0200 Ramiro Aceves [EMAIL PROTECTED] wrote: || Eureka!, Señor SoTaNeZ, usted sabe latín, ha dado en el clavo. Por || favor, ¿me puede usted explicar el por qué del asunto? Aquí estoy con mi || C manual de Referencia, 3ª edición, de Herbert Schildt mas sobao que || yo que sé y por más vueltas que le doy no me entero. || || Todavía sigo sin entender por qué falla getchar ( a veces). || || Gracias.! || De latín nada jejeje. A mi me pasaba lo mismo. Me lo dijeron en el irc creo o en algún foro y me dieron la explicación pero ahora mismo no me acuerdo. Tenía algo que ver con lo que te han dicho sobre hacer el flush y todo eso. Desde luego tiene que ver sobre la forma en que funciona internamente scanf, pero como ya te he dicho ahora mismo ni idea. Siento no poder ayudarte más :(. Saludos.
problema con scanf (novato)
Hola amigos. No se si es el lugar más adecuado para preguntar esto, si no lo es por favor decídme dónde. Hoy me puse a practicar C con un pequeño programita. El objetivo del programa es muy sencillo, partiendo de la longitud de los elementos de una antena yagi para radioaficionado introducidos por el teclado, generar por la salida estándar el formato adecuado de entrada para el programa de simulación NEC2 (nummerical electromagnetic code). Bueno, el caso es que no pasaron ni 20 minutos y ya me he quedado estancado en algo que quizás para vosotros sea algo trivial, pero por más que miro no le veo el fallo. El problema es que el programa se salta la instrucción respuesta=getchar(); Para que me funcione debo poner dos líneas iguales: respuesta=getchar(); respuesta=getchar(); ¿Alguien me puede aportar alguna idea? Muchas gracias. /*this program generates a *.NEC file for yagi antenna modelling*/ #include stdio.h int N; int a; char respuesta='n'; float longitud[100]; void main(void){ printf(number of elements? [1-100]\n); scanf(%d,N); while(respuesta=='n') { printf(enter element length, starting from reflector to last director [mm]\n); for (a=0;aN;a++){ printf(element number %d : ,a); scanf(%f,longitud+a); } printf(You have entered:\n); for (a=0;aN;a++){ printf(element number %d : ,a); printf(%f\n,*(longitud+a)); } printf(is data correct? [y/n]\n); respuesta=getchar(); respuesta=getchar(); } }
Re: problema con scanf (novato)
El problema es porque getchar() no espera a que des a Intro para guardar el caracter introducido por teclado. Lo que ocurre es que antes hay que limpiar el buffer de entrada porque si no getchar adquiere el valor en él contenido (que suele ser un Intro al haber metido antes otro dato). Para ello, prueba a poner justo antes del getchar, la siguiente línea: fflush(stdin); Me comentas si te funciona o no. El Domingo, 20 de Junio de 2004 13:17, Ramiro Aceves escribió: || Hola amigos. || No se si es el lugar más adecuado para preguntar esto, si no lo es por || favor decídme dónde. || Hoy me puse a practicar C con un pequeño programita. El objetivo del || programa es muy sencillo, partiendo de la longitud de los elementos de || una antena yagi para radioaficionado introducidos por el teclado, || generar por la salida estándar el formato adecuado de entrada para el || programa de simulación NEC2 (nummerical electromagnetic code). Bueno, el || caso es que no pasaron ni 20 minutos y ya me he quedado estancado en || algo que quizás para vosotros sea algo trivial, pero por más que miro no || le veo el fallo. || || El problema es que el programa se salta la instrucción || respuesta=getchar(); || Para que me funcione debo poner dos líneas iguales: || || respuesta=getchar(); || respuesta=getchar(); || || ¿Alguien me puede aportar alguna idea? || Muchas gracias. || || /*this program generates a *.NEC file for yagi antenna modelling*/ || || #include stdio.h || int N; || int a; || char respuesta='n'; || float longitud[100]; || void main(void){ || || printf(number of elements? [1-100]\n); || scanf(%d,N); || || || while(respuesta=='n') || { || printf(enter element length, starting from reflector to last director || [mm]\n); || for (a=0;aN;a++){ || printf(element number %d : ,a); || scanf(%f,longitud+a); || || } || printf(You have entered:\n); || for (a=0;aN;a++){ || printf(element number %d : ,a); || printf(%f\n,*(longitud+a)); || || } || || printf(is data correct? [y/n]\n); || respuesta=getchar(); || respuesta=getchar(); || || } || || || || || || }
Re: problema con scanf (novato)
Mejor aun, pon siempre fflush(stdin); después de cualquier scanf.
Re: problema con scanf (novato)
Iñaki escribió: Mejor aun, pon siempre fflush(stdin); después de cualquier scanf. Hola Iñaki. Muchas gracias por tu ayuda, pero no me funciona tampoco, no entiendo nada. ( y mira que tenía buena pinta lo que me dices). Tampoco me va con scanf(%c,respuesta). Sigo investigando, a la espera de alguna otra idea que se os ocurra. :-( Gracias. Ramiro.
Re: problema con scanf (novato)
El Domingo, 20 de Junio de 2004 15:42, Ramiro Aceves escribió: || Iñaki escribió: || Mejor aun, pon siempre fflush(stdin); después de cualquier scanf. || || Hola Iñaki. Muchas gracias por tu ayuda, pero no me funciona tampoco, no || entiendo nada. ( y mira que tenía buena pinta lo que me dices). Tampoco || me va con scanf(%c,respuesta). || || Sigo investigando, a la espera de alguna otra idea que se os ocurra. :-( || || Gracias. || Ramiro. Vaya, pues yo es que es algo que hace años usaba mucho y me funcionaba. No sé, ¿has probado con getch() ó getche() ? Son iguales que el getchar pero no tienes que pulsar Intro, nada más introducir un carácter se guarda en la variable asociada. La diferencia entre ellos es que getch() es sin eco (no se visualiza el caracter que introduces en pantalla) y getche() sí. Eso sí, lo del fflush(stdin) después de cada scanf() yo juraría que es siempre recomendable. A ver si te vale con esto. O si necesitas por diseño que sea getchar() alguien seguro que sabe dónde está el fallo. Suerte.
Re: problema con scanf (novato)
On Sun, 20 Jun 2004 15:50:47 +0200 Iñaki [EMAIL PROTECTED] wrote: || El Domingo, 20 de Junio de 2004 15:42, Ramiro Aceves escribió: || || Iñaki escribió: || || Mejor aun, pon siempre fflush(stdin); después de cualquier scanf. || || || || Hola Iñaki. Muchas gracias por tu ayuda, pero no me funciona tampoco, no || || entiendo nada. ( y mira que tenía buena pinta lo que me dices). Tampoco || || me va con scanf(%c,respuesta). || || || || Sigo investigando, a la espera de alguna otra idea que se os ocurra. :-( || || || || Gracias. || || Ramiro. Prueba scanf( %c,respuesta) Incluye el espacio jeje.
Re: problema con scanf (novato)
Iñaki escribió: El Domingo, 20 de Junio de 2004 15:42, Ramiro Aceves escribió: || Iñaki escribió: || Mejor aun, pon siempre fflush(stdin); después de cualquier scanf. || || Hola Iñaki. Muchas gracias por tu ayuda, pero no me funciona tampoco, no || entiendo nada. ( y mira que tenía buena pinta lo que me dices). Tampoco || me va con scanf(%c,respuesta). || || Sigo investigando, a la espera de alguna otra idea que se os ocurra. :-( || || Gracias. || Ramiro. Vaya, pues yo es que es algo que hace años usaba mucho y me funcionaba. No sé, ¿has probado con getch() ó getche() ? getche() no lo tengo, y getch parece que necesita curses.h Son iguales que el getchar pero no tienes que pulsar Intro, nada más introducir un carácter se guarda en la variable asociada. La diferencia entre ellos es que getch() es sin eco (no se visualiza el caracter que introduces en pantalla) y getche() sí. Eso sí, lo del fflush(stdin) después de cada scanf() yo juraría que es siempre recomendable. No lo entiendo, aquí getchar() requiere que se pulse intro, al menos así lo hace en un programín que he hecho ahora para probar. A ver si te vale con esto. O si necesitas por diseño que sea getchar() alguien seguro que sabe dónde está el fallo. No, me da igual con tal de que funcione, es solo curiosidad por qué pasan estas cosas, hay que ver, el C es bonito, pero es un poco perro :-) Suerte.
Re: problema con scanf (novato)
SoTaNeZ escribió: On Sun, 20 Jun 2004 15:50:47 +0200 Iñaki [EMAIL PROTECTED] wrote: || El Domingo, 20 de Junio de 2004 15:42, Ramiro Aceves escribió: || || Iñaki escribió: || || Mejor aun, pon siempre fflush(stdin); después de cualquier scanf. || || || || Hola Iñaki. Muchas gracias por tu ayuda, pero no me funciona tampoco, no || || entiendo nada. ( y mira que tenía buena pinta lo que me dices). Tampoco || || me va con scanf(%c,respuesta). || || || || Sigo investigando, a la espera de alguna otra idea que se os ocurra. :-( || || || || Gracias. || || Ramiro. Prueba scanf( %c,respuesta) Incluye el espacio jeje. Eureka!, Señor SoTaNeZ, usted sabe latín, ha dado en el clavo. Por favor, ¿me puede usted explicar el por qué del asunto? Aquí estoy con mi C manual de Referencia, 3ª edición, de Herbert Schildt mas sobao que yo que sé y por más vueltas que le doy no me entero. Todavía sigo sin entender por qué falla getchar ( a veces). Gracias.!