Analicemos paso a paso el programa.
Cuando se ejecute esta línea:
printf("Enter names and surnames: ");
scanf("%c", &nombre);
El usuario solo puede ingresar un caracter. Por ejemplo, la letra A
y este caracter se guardaría en la primera posición del array nombre
(es decir, en nombre[0]
).
Esto quiere decir, que si solo ingresas un caracter, el búfer del teclado quedaría con un salto de línea, esto no afectará al próximo scanf
, ya que ignorará el salto de línea.
Si el usuario ingresara como altura: 12.3
. El búfer sigue quedando con el \n
.
printf("\nEnter height in meters: ");
scanf(" %f", &h);
Esto ocasiona que la función gets
nunca se detenga para la espera de una cadena y esto se debe a que esta rutina deja de leer hasta encontrar un salto de línea.
gets(nombre);
Después se imprime los datos que ingresó el usuario:
printf("\nYour height is %f, and your initials are %c", h, nombre[0]);
Dándome como resultado:
Your height is 12.3, and your initials are
Por supuesto, no se está imprimiendo el contenido de la primera posición del array nombre
y esto se debe que la función gets
como no pudo leer nada, asignó el caracter nulo en nombre[0]
y dicho caracter no se lo puede imprimir con %c
(sino con %d
).
Hasta ahí, podríamos comprender como podría funcionar tu código ingresando esos datos.
Veamos otro caso. Si en la primera llamada de scanf
ingreso un Ramirez
, solo tomará el primer caracter de la cadena (la letra R
), el resto se quedará en el búfer: amirez
.
scanf("%c", &nombre);
El próximo scanf
pide un flotante y solo ignora saltos de líneas pero como en el búfer quedó con mas caracteres, esto provoca que la lectura falle y esa es la razón del porque se salta la opción.
El problema no ocurre cuando utilizo "%s" en vez de "%c", pero intento leer caracteres individualmente así que no sé si es una opción.
Si haces algo como esto:
printf("Enter names and surnames: ");
scanf("%s", &nombre);
La función scanf
leerá los caracteres del búfer hasta encontrar un espacio o salto de línea. Esto es peligroso, aquí puedes desbordar el array nombre
y esto provoca que scanf
escriba en alguna dirección de memoria que no le corresponda al programa. En este hilo puedes encontrar mas información sobre eso: ¿Cómo evitar un desbordamiento de búfer cuando se pide una cadena con scanf?
. De igual manera, en tu caso deberías de utilizar una función que si te permita leer cadenas con espacios.
Pero no, no debes usar la función gets
. Es peligroso, también puedes desbordar el búfer. Para mas información, leer este hilo: Es recomendable usar la función gets?.
La función que conozco para leer cadenas con espacios y que sea seguro, es la función fgets.
Su uso es sencillo:
printf("Enter names and surnames: ");
fgets(nombre, sizeof nombre, stdin);
printf("\nEnter height in meters: ");
scanf("%f", &h);
De esta manera haces una lectura de forma segura. Un detalle importante es que la función fgets
agregaría el salto de línea en el array. Eso se lo podría eliminar de esta forma:
nombre[strlen(nombre) - 1] = '\0';
Y eso es todo..
El último código no tengo ni idea del porque lo usaste. Si quieres imprimir la cadena, simplemente usa:
printf("name and surname: %s", nombre);