[C con Clase] Leer el salto de linea con scanf
Steven R. Davidson
vze266ft en verizon.net
Jue Mar 13 22:22:00 CET 2008
Hola Sergio,
Sergio Hernández wrote:
> ¡Hola!
>
> Estoy haciendo un programa con un menú y para leer las diferentes
> opciones ("strings") utilizao la función scanf() pero me surge el
> problema de que la función no me coge el esalto de línea y entonces este
> es leido por el siguiente scanf().
>
Esto no debería ocurrir. La función 'scanf()', por defecto, lee
caracteres hasta encontrarse con un espacio blanco: ' ', '\t', '\r',
'\n', '\v', o '\f'. Al leer caracteres, el espacio blanco, que sirve
como separador, es leído, extraído, pero descartado.
Lo que sí puede ocurrir es que previamente hayas usado 'scanf()' para
leer una cadena para ser interpretada como un número. En este caso, al
leer cualquier carácter no perteneciente a la representación de un
número, la lectura y conversión se detiene sin extraer tal carácter. Por
lo tanto, éste se queda en el canal de entrada esperando su extracción.
Por ejemplo,
int nNumero;
char szNombre[128];
scanf( "%d", &nNumero );
scanf( "%s", szNombre );
El usuario escribe: 32[ENTER]Sergio[ENTER]
Obtendríamos,
canal de entrada <- "32\nSergio\n"
En la primera lectura:
canal de entrada <- "\nSergio\n"
nNumero <- 32
En la segunda:
canal de entrada <- "Sergio\n"
nNumero <- 32
szNombre <- "\0"
En este caso, podrías extraer el próximo carácter '\n' con 'getchar()'.
Por ejemplo,
scanf( "%d", &nNumero );
getchar();
scanf( "%s", szNombre );
> Para solucionar esto he encontrado dos opciones pero no me gustan nada y
> por eso pido ayuda para ver si alguien puede solucionarme el problema.
>
> 1.- Utilizar la función gets, pero no quiero usar esta alternativa dado
> que la función no es segura y está desaconsejado su uso.
Efectivamente, no es aconsejable, pero en su lugar puedes usar
'fgets()'. Esta función es casi igual a 'gets()'. La característica que
te interesa es que guarda el carácter de fin-de-línea, '\n', en la cadena.
> 2.- Hacer un getchar() después del scanf() pero me parece una "guarrada"
>
Entiendo. Otra solución es consultar el siguiente carácter para tomar
una decisión. Por ejemplo,
int c = getchar();
if( '\n' != c || EOF != c )
{
// Cualquier otro carácter: devolución
ungetc( c );
}
// Si es '\n', no hacer nada: descartar
Otra posibilidad es leer cadenas de caracteres y luego procesarlas tú
mismo. Esto es especialmente conveniente si estamos leyendo números.
Podemos extraer la cadena hasta un separador (un espacio blanco) y luego
averiguar cuáles caracteres nos interesa y cuáles no.
Espero que esto te ayude.
Steven
Más información sobre la lista de distribución Cconclase