scanf peta al introducir una letra

O

Wenas, tengo un programita en c, en la que en un momento dado le pido al usuario q introduzca un numero de opcion desde la consola, si introduces un numero todo va bien, pero si pones una letra el programa falla, estoy programando en visual c++.

Habia pensado para evitarlo en vez de usar scanf usar getchar, y ver si me ha introducido una letra o un numero, y si es un numero convertirlo con atoi a numero entero.

Y weno mi pregunta es, esta solucion que he pensado que tal es?, se os ocurre a vosotros alguna mas elegante.

Un saludo.

E

En que tipo de variable estas intentando meter el dato? Si lo estas metiendo en un "int" es normal que te fallo al introducirle una letra, sin embargo si usas una variable "char", te debe aceptar tanto numeros como letras.

javithelong

Has puesto la dirección de memoria de la variable en la que vas a insertar el caracter? scanf necesita puntero, no valor (en el 2º parámetro)

Si, mas elegante es fgets, y luego parsear la cadena con sscanf, atoi, o lo que quieras (sin usar strtok ^^)

Saludos

O

Wenas, perdon por la info que dije, era un poco incompleta, yo lo que quiero es guardarlo en formato int, pq luego hago calculos con ese numero, asi q hare lo de guardarlo en cadena y luego convertirlo.

El problema esta mas bien en scanf, que al introducir una letra no se q hara q hace q el programa falle.

Otra solucion que acabo de pensar es ver cual es el valor que devuelve scanf cuando se le mete una letra y asi poder saber cuando ha habido error, lo mirare ahora y ya os contare.

Gracias a todos por responder un saludo :).

maRc

scanf devuelve el número de conversiones que ha hecho de la entrada, que será entre 0 (si no ha hecho ninguna) y el número de %loquesea que le pases (si las ha hecho todas), o EOF si no ha podido leer la entrada.

Si haces scanf("%d", &n); el scanf trata de leer un entero. Si introduces un entero, devolverá uno. Si le metes cualquiera otra cosa, devolverá 0.

Pega tu código para ver que es exactamente lo que quieres que hacer (que no se te entiende demasiado bien :P).

O

printf("\nIntroduzca el tiempo de entrada: ");
scanf("%d", &instantes);

Este es el trozito de codigo lo q hago es tratar de evitar qsi el usuario se confunde y pone una letra pos el programa falle, la idea es q si pone una letra yo diga error debe introducir un numero, y le vuelvo a preguntar el tiempo de entrada, pero segun pones simplemente con comprobar si scanf ha devuelto un 0 ya puedo darme cuenta si ha puesto una letra.

dr_Rouman

Con esto puedes comprobarlo y evitar que el programa siga ejecutándose si el usuario se equivoca.

#include <stdio.h>

main()
{
int a, devuelve;
printf("Introduce un número: ");
devuelve=scanf("%d", &a);
while(!devuelve)
{
printf("\nHas introducido una letra, gañán. Introduce un numero: ");
getchar();//Como quites este getchar() te entra la risa
devuelve=scanf("%d", &a);
}
a++;
printf("%d", a);
return 0;
}

#2 No tiene ni puta idea :P

O

Wenas thx por el codigo, lo he modificado un poco quitando la variable devuelve, y quitando ese getchar(), aqui te lo pongo.

#include <stdio.h>

main()
{
int a;
printf("Introduce un número: ");

while(!scanf("%d", &a) )
{
printf("\nHas introducido una letra, gañán. Introduce un numero: ");
fflush(stdin);

}

return 0;
}

En vez de getchar he limpiado el buffer con fflush, me gusta mas asi que con el getchar.

dr_Rouman

Ostia, no sabía que el fflush servía para eso, ¡gracias a tí!

Va a ser verdad eso de que no te acuestas sin saber nada nuevo ^^

Un Saludo!

O

#include <stdio.h>

main()
{
int a;
printf("Introduce un número: ");

while(!scanf("%d", &a) )
{
printf("\nHas introducido una letra, gañán. Introduce un numero: ");
fflush(stdin);

}

return 0;
}

Wenas, a ver si alguien me echa una mano postee ese codigo, en el que utilize fflush(stdin) para limpiar el buffer de entrada, pero buscando mas info, fflush(stdin) no es ansi c, y en el programa q ando haciendo para la uni, si q lo suelo usar, pero al no ser ansi ya me puedo ir olvidando de él, asi q hay alguno conoce alguna forma de limpiar el buffer de entrada siguiendo el ansi c?.

O

Wenas, me respondo a mi mismo, segun he leido, los expertos dicen q es mejor no usar nunca scanf por unos cuantos problemillas que podreis leer aqui http://c-faq.com/stdio/scanfprobs.html

Y weno para no usar fflush(stdin) (q no es ansi c), me he hecho mi propia funcion que haga lo q necesito esta es.

void mifflush()
{
int ch;

while ( (ch = getchar()) != '\n' && ch != EOF );

}

Lo que hace es ir leyendo caracteres desde stdin hasta q encuentra un \n o un EOF, espero q sea de ayuda a alguien un saludo.

maRc

No es ANSI C, pero estándar ISO, por lo que supongo que tu profesor te lo aceptará.

Otra manera cutre de hacerlo es while (getchar() != EOF);

Edito: Pues eso mismo :P

javithelong

fgets + fscanf o atoi esa combinación es lo mejor que hay para leer de teclado, fichero o de donde sea.

Saludos

Shakurita

perdonen mi ignorancia, pero en:
#include <stdio.h>

main()
{
int a, devuelve;
printf("Introduce un número: ");
devuelve=scanf("%d", &a);
while(!devuelve)
{
printf("\nHas introducido una letra, gañán. Introduce un numero: ");
getchar();//Como quites este getchar() te entra la risa
devuelve=scanf("%d", &a);
}
a++;
printf("%d", a);
return 0;
}

lo que está en negrita no lo entiendo, que significa, mientras .. qué? q hace eso q detecte q has metido una letra y no un numero?

dr_Rouman

#14 while(!expresión) quiere decir, mientras expresión sea falsa. Es decir, sería lo mismo si hubiese puesto: while(devuelve==0). En general en C, falso es 0 y todo lo demás es verdadero.

Un saludo!

Shakurita

ajammm muchas gracias, osea q si mete un numero (devuelve tomara un valor numerico..) eso es verdadero y si mete un letra (devuelve toma la letra) eso es falso? y mientras q eso sea no verdadero (osea falso) se repetira?

dr_Rouman

#16 Exacto. scanf devuelve el número de conversiones, o algo así, que realiza (está explicado más arriba, por marC, creo) cuando le metes algo que no espera, devuelve 0. Como en este caso, que espera un número, pero le metes una letra. Luego ya ese bucle se ejecutará mientras esa condición valga 0, como bien dices.

Un Saludo!

Shakurita

juuuuums muchas gracias :D

Usuarios habituales