Dev - C++ - Problemas con la sentencia de iteracion for

 
Vista:
sin imagen de perfil
Val: 22
Ha disminuido su posición en 3 puestos en Dev - C++ (en relación al último mes)
Gráfica de Dev - C++

Problemas con la sentencia de iteracion for

Publicado por Santiago (8 intervenciones) el 18/08/2020 00:45:33
ayuda-en-la-pagina

El ejercicio me pide ingresar 10 letras y contar cuantas 'a' se ingresan y cuantas 'e', 'i', 'o' y 'u'.
Pero solo me deja ingresar 5 y no entiendo por que.
Si alguien me puede ayudar, gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 91
Ha disminuido 1 puesto en Dev - C++ (en relación al último mes)
Gráfica de Dev - C++

Problemas con la sentencia de iteracion for

Publicado por Kabuto (21 intervenciones) el 18/08/2020 02:05:01
Mira, si pruebas a añadir una linea para que en cada iteración del bucle te muestre en pantalla que valor tiene la variable i, la que incrementa el bucle for, percibirás una cosa curiosa:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main() {
	int c1=0, c2=0;
	char car;
	printf("Ingrese una letra\n");
	for(int i=0;i<9;i++) {
		printf("\ni = %d\n", i);//Mostramos valor de i en pantalla
		scanf("%c",&car);
		switch(car) {
		case 'a':
			c1++;
			break;
		case 'e':
			c2++;
			break;
		case 'i':
			c2++;
			break;
		case 'o':
			c2++;
			break;
		case 'u':
			c2++;
			break;
		}
	}
	printf("Letras igual a A=%d\tDemas vocales=%d",c1,c2);
	return 0;
}

Este es el resultado en pantalla, fíjate que cada vez que entramos un carácter, la i se incrementa dos veces.
Es decir, hay ciclos del bucle que transcurren sin que hayamos podido entrar una letra, los señalo con comentarios a continuación, ¿por qué?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Ingrese una letra
 
i = 0
a
 
i = 1
//Aquí no nos ha pedido ingresar caracter
i = 2
a
 
i = 3
//Aquí tampoco
i = 4
a
 
i = 5
//Ni aquí :-0
i = 6
a
 
i = 7
//Nada, que no nos deja entrar un caracter :-(
i = 8
a
Letras igual a A=5      Demas vocales=0


Esto se debe a que cuando sí nos deja entrar el carácter, para entrarlo, tenemos que teclear carácter y a continuación pulsar tecla enter, que genera su propio carácter (es un carácter especial, pero carácter al fin y al cabo).
La variable char recoge el primer carácter que hemos pulsado, pero no coge la pulsación de la tecla enter, porque no cabe, solo admite un único carácter.
Este carácter de la tecla enter se queda en el stream de entrada de datos, entonces, en la siguiente iteración, cuando nos va a pedir ingresar otro carácter, scanf() se encuentra la pulsación de enter que había quedado "olvidada" de la vez anterior.
Y erróneamente piensa que el usuario ha vuelto a pulsar enter, así que ahora sí recoge este carácter, lo pasa por el switch y repite el bucle de nuevo.
Esta vez como el stream ya ha quedado vacío, ahora si tenemos ocasión de volver a teclear.

No se si me he explicado bien...

Bueno, ¿solución?
Una solución es usar fflush() para limpiar el stream de entrada. Aunque parece ser que no es aconsejable porque fflush() está pensado para streams de salida de datos, no de entrada.
Entonces no está garantizado que funcione e incluso puede tener comportamientos inesperados.
Yo lo he probado, y si me funciona. Lo marco en negrita

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int main() {
	int c1=0, c2=0;
	char car;
	printf("Ingrese una letra\n");
	for(int i=0;i<9;i++) {
		printf("\ni = %d\n", i);
		scanf("%c",&car);
		fflush(stdin);//Limpiamos stream de entrada
		switch(car) {
		case 'a':
			c1++;
			break;
		case 'e':
			c2++;
			break;
		case 'i':
			c2++;
			break;
		case 'o':
			c2++;
			break;
		case 'u':
			c2++;
			break;
		}
	}
	printf("Letras igual a A=%d\tDemas vocales=%d",c1,c2);
	return 0;
}

Otra opción es simplemente volver a hacer un scanf() seguido, o un simple getchar(), para recoger el caracter de la tecla enter. Lo recogemos para quitarlo del stream de entrada y que no moleste, no haremos ninguna operación con él.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int main() {
	int c1=0, c2=0;
	char car;
	printf("Ingrese una letra\n");
	for(int i=0;i<9;i++) {
		printf("\ni = %d\n", i);
		scanf("%c",&car);
		getchar();//Recogemos carácter de tecla ENTER(retorno de carro)
		switch(car) {
		case 'a':
			c1++;
			break;
		case 'e':
			c2++;
			break;
		case 'i':
			c2++;
			break;
		case 'o':
			c2++;
			break;
		case 'u':
			c2++;
			break;
		}
	}
	printf("Letras igual a A=%d\tDemas vocales=%d",c1,c2);
	return 0;
}

Y con eso queda solucionado.

Por cierto, dices que se han pedir 10 números, pero tal y como has puesto el for solo se piden 9.
Y te reescribo el switch de otra forma distinta que hace lo mismo, pero ahorras líneas.
Cuando hay varios cases que van a tener el mismo código, puedes unirlos de esta manera y escribir ese código solo una vez.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main() {
	int c1=0, c2=0;
	char car;
	printf("Ingrese una letra\n");
	for(int i=0;i<10;i++) {
		scanf("%c",&car);
		getchar();//Recogemos carácter de tecla ENTER(retorno de carro)
		switch(car) {
		case 'a':
			c1++;
			break;
		case 'e':
		case 'i':
		case 'o':
		case 'u':
			c2++;
			break;
		}
	}
	printf("Letras igual a A=%d\tDemas vocales=%d",c1,c2);
	return 0;
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 22
Ha disminuido su posición en 3 puestos en Dev - C++ (en relación al último mes)
Gráfica de Dev - C++

Problemas con la sentencia de iteracion for

Publicado por Santiago (8 intervenciones) el 18/08/2020 15:00:12
Se entendio todo a la perfeccion, muchas graciass
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar