usando - Scanf omite cada otro ciclo while en C
lenguaje c if else ejemplos (10)
Newlines.
La primera vez a través del ciclo, scanf () lee el personaje. Luego lee la nueva línea. Luego lee el siguiente caracter; repetir.
¿Como arreglar?
Rara vez uso scanf (), pero si usa una cadena de formato "%.1s"
, debe omitir el espacio en blanco (incluidas las líneas nuevas) y luego leer un carácter de espacio que no sea en blanco. Sin embargo, esperará una matriz de caracteres en lugar de un solo carácter:
char ibuff[2];
while ((scanf("%.1s", ibuff) == 1)
{
...
}
Intento desarrollar un simple juego de ahorcado basado en texto, y el ciclo principal del juego comienza con un aviso para ingresar una suposición a cada letra, luego continúa para verificar si la letra está en la palabra y se quita la vida si no es Sin embargo, cuando ejecuto el juego aparece el aviso dos veces cada vez, y el programa no espera la entrada del usuario. También quita una vida (una vida si era la entrada correcta, dos si no lo era), así que lo que sea que tome no es lo mismo que la entrada anterior. Aquí está mi bucle de juego, simplificado un poco:
while (!finished)
{
printf("Guess the word ''%s''/n",covered);
scanf("%c", ¤tGuess);
i=0;
while (i<=wordLength)
{
if (i == wordLength)
{
--numLives;
printf("Number of lives: %i/n", numLives);
break;
} else if (currentGuess == secretWord[i]) {
covered[i] = secretWord[i];
secretWord[i] = ''*'';
break;
}
++i;
}
j=0;
while (j<=wordLength)
{
if (j == (wordLength)) {
finished = 1;
printf("Congratulations! You guessed the word!/n");
break;
} else {
if (covered[j] == ''-'') {
break;
}
}
++j;
if (numLives == 0) {
finished = 1;
}
}
}
Supongo que el problema es escanear, pensando que se tomó algo cuando no lo hizo, pero no tengo idea de por qué. ¿Alguien tiene alguna idea? Estoy usando gcc 4.0.1 en Mac OS X 10.5.
Adivinaré: su código trata una nueva línea como una de las suposiciones cuando ingresa datos. Siempre evité la familia * scanf () debido al manejo incontrolable de errores. Intenta usar fgets () en su lugar, luego saca el primer char / byte.
Cuando lee la entrada del teclado con scanf()
, la entrada se lee después de presionar enter, pero la nueva línea generada por la tecla enter no es consumida por la llamada a scanf()
. Eso significa que la próxima vez que lea desde la entrada estándar habrá una nueva línea esperando por usted (lo que hará que la próxima llamada scanf()
vuelva al instante sin datos).
Para evitar esto, puede modificar su código a algo como:
scanf("%c%*c", ¤tGuess);
El %*c
coincide con un solo carácter, pero el asterisco indica que el carácter no se almacenará en ningún lugar. Esto tiene el efecto de consumir el carácter de línea nueva generado por la tecla Intro para que la próxima vez que llame a scanf()
comience con un búfer de entrada vacío.
Advertencia: si el usuario presiona dos teclas y luego presiona enter, scanf()
devolverá la primera pulsación de tecla, comerá la segunda y abandonará la nueva línea para la siguiente llamada de entrada. Los inconvenientes como este son una de las razones por las que scanf()
y amigos son evitados por muchos programadores.
Divide el problema en partes más pequeñas:
int main(void) {
char val;
while (1) {
printf("enter val: ");
scanf("%c", &val);
printf("got: %d/n", val);
}
}
El resultado aquí es:
enter val: g
got: 103
enter val: got: 10
¿Por qué scanf
te daría otro ''10'' allí?
Dado que imprimimos el número ASCII para nuestro valor, ''10'' en ASCII es "enter", por lo que scanf
también debe tomar la tecla "enter" como un carácter.
Efectivamente, mirando su secuencia scanf
, usted está pidiendo un solo carácter cada vez a través de su ciclo. Los personajes de control también se consideran personajes y serán recogidos. Por ejemplo, puede presionar "esc" y luego "enter" en el ciclo de arriba y obtener:
enter val: ^[
got: 27
enter val: got: 10
Jim y Jonathan tienen razón.
Para que su línea scanf haga lo que quiera (consuma el carácter de nueva línea sin ponerlo en el búfer) lo cambiaría a
scanf("%c/n", ¤tGuess);
(nota el /n
)
Sin embargo, el manejo de errores es atroz. Por lo menos, debe verificar el valor de retorno de scanf contra 1, e ignorar la entrada (con una advertencia) si no lo devuelve.
Solo supongo, pero está ingresando un solo carácter con scanf, pero el usuario debe escribir la conjetura más una nueva línea, que se está consumiendo como un carácter de conjetura por separado.
Un par de puntos que noté:
-
scanf("%c")
leerá 1 carácter y mantendrá el ENTER en el búfer de entrada para la próxima vez a través del bucle - estás incrementando
i
incluso cuando el carácter leído por el usuario no coincide con el carácter en lasecretWord
- ¿Cuándo el
covered[j]
llega a ser ''-''?
Veo un par de cosas en tu código:
- scanf devuelve la cantidad de elementos que leyó. Es probable que desee manejar los casos en los que devuelve 0 o EOF.
- Supongo que el usuario está presionando la letra + Enter y obtendrá la nueva línea como segundo personaje. Una manera fácil de verificar sería agregar una declaración printf de depuración para mostrar qué carácter se ingresó.
- Su código solo coincidirá con la primera aparición de una letra de coincidencia, es decir, si la palabra fue "prueba" y el usuario ingresó "t", su código solo coincidirá con la primera "t", no con ambas. Necesita ajustar su primer ciclo para manejar esto.
Cuando ingrese el carácter, debe ingresar un carácter de espacio en blanco para continuar. Este carácter de espacio en blanco está presente en el búfer de entrada, archivo stdin, y es leído por la función scanf (). Este problema se puede resolver consumiendo este personaje extra. Esto se puede hacer mediante la función usnig getchar ().
scanf ("% c", & currentGuess);
getchar (); // Para consumir el carácter de espacio en blanco.
Prefiero sugerir que evite usar scanf () y en su lugar use getchar (). El scanf () requiere mucho espacio de memoria. getchar () es una función de luz. Entonces también puedes usar-
char currentGuess;
currentGuess = getchar ();
getchar (); // Para consumir el carácter de espacio en blanco.
scanf(" %c", &fooBar);
Observe el espacio antes del %c
. Esto es importante porque coincide con todos los espacios en blanco anteriores.