¿Cuál es la diferencia entre scanf("%d")
y scanf("%d ")
en este código, ¿dónde está la diferencia en el espacio en blanco final en la cadena de formato?
#include <stdio.h>
int main(void)
{
int i, j;
printf("enter a value for j ");
scanf("%d ",&j);
printf("j is %d\n", j);
printf("enter a value for i ");
scanf("%d", &i);
printf("i is %d\n", i);
return 0;
}
Cómo hace el scanf()
la función realmente funciona cuando agrego espacios después del especificador de formato como scanf("%d ", &j);
?
Un carácter de espacio en blanco en un formato scanf hace que lea e ignore explícitamente tantos caracteres de espacio en blanco como sea posible. Así que con scanf("%d ", ...
, después de leer un número, continuará leyendo caracteres, descartando todos los espacios en blanco hasta que vea un carácter que no sea un espacio en blanco en la entrada. Ese carácter que no sea un espacio en blanco se dejará como el siguiente carácter que leerá una función de entrada.
Con tu código:
printf("enter a value for j ");
scanf("%d ",&j);
printf("j is %d \n", j);
imprimirá la primera línea y luego esperará a que ingrese un número, y luego seguir esperando algo después el número. Así que si solo escribes 5Ingresar, parecerá colgarse; debe escribir otra línea con algún carácter que no sea un espacio en blanco para continuar. Si luego escribes 6Ingresarque se convertirá en el valor de i
por lo que su pantalla se verá algo como:
enter a value for j 5
6
j is 5
enter a value for i i is 6
Además, dado que la mayoría de las conversiones scanf % también omiten los espacios en blanco iniciales (todos excepto %c
, %[
and %n
), spaces before %-conversions are irrelevant ("%d"
and " %d"
will act identically). So for the most part, you should avoid spaces in scanf conversions unless you know you specifically need them for their peculiar effect.
A white-space character (space, newline, horizontal and vertical tab) in a format string matches any number of white-space characters in the input.
In your first case
scanf("%d ",&j);
when it encounters the white-space char (WSC) ' '
then it will eat all the white spaces input by user including \n
on pressing Enter and it will expect to enter a non-WSC . In this case your program will terminate by pressing Ctrl + Z.
A whitespace character in your scanf
format matches any number of whitespace characters as described by isspace
. So if you have tailing spaces, newlines, tabulators or any other whitespace character then it will also be consumed by scanf
before it returns.
The difference (although obvious) is a different format string. If you enter the following line:
"3 "
scanf()
will return successfully. Otherwise, it depends on your input provided. scanf()
essentially skips over whitespace (tabs, spaces, newlines), and searches for alphanumeric values in the input stream. Since this is trailing whitespace, it gets lumped in with the trailing newline character at the end of input when pressing ENTER, so it’s of little consequence.
scanf()
expects the input provided to exactly match the format string you provide to it, with the exception that contiguous whitespace characters are compressed to a single whitespace character. This becomes very important if you want to parse large strings of data with it’s string-processing equivalent, sscanf()
.
A good exercise to further test this would be something like:
#include<stdio.h>
int main(void)
{
int a=0,b=0,c=0;
printf("Enter values for A, B, C, in the format: \"A B - C\"\n");
scanf("%d %d - %d", &a, &b, &c);
printf("Values: A:%d, B:%d, C:%d\n", a, b, c);
}
Afterwards, check and see what the values of these integers are after providing both correctly and incorrectly formatted consoled input (ie: spaces and hyphens). Here are a couple example runs. The first used incorrect input, the second used correctly formatted input. Notice that in the first case, C
doesn’t even get set, as scanf()
will provided unexpected behavior if the input and the format strings don’t match up. In general, you are better off using something like fgets()
to get a string of input from the user, and then use various search functions (ie: strstr(), strch(), strcat, strcpy, etc) to parse your string, as it is much safer than just using scanf()
and assuming the user won’t make a mistake, either accidentally or deliberately.
Enter values for A, B, C, in the format: "A B - C"
1 2 3
Values: A:1, B:2, C:0
Enter values for A, B, C, in the format: "A B - C"
1 2 - 3
Values: A:1, B:2, C:3
Now, consider one last run: You’ll see that scanf()
compacts multiple consecutive whitespace characters to a single character, hence why these final runs actually succeeds:
Enter values for A, B, C, in the format: "A B - C"
1 2 - 3
Values: A:1, B:2, C:3
Enter values for A, B, C, in the format: "A B - C"
1 2 - 3
Values: A:1, B:2, C:3
¿Quizás deberíamos cambiar el nombre del título para que sea más general?
– Stargateur
19 de abril de 2018 a las 4:13
@Stargateur ¿puedes sugerir?
– Vikas Verma
23 de abril de 2018 a las 10:37
Estaba pensando en eliminar “trasero”
– Stargateur
23 de abril de 2018 a las 15:51
@Stargateur ¿Por qué deberías querer hacer eso? La pregunta (y las respuestas también) está/están claramente enfocadas en una cadena de formato con arrastrando espacio en blanco, no principal uno (que, por supuesto, puede ser beneficioso y es objeto de otras preguntas de SO). Hay una gran diferencia entre los dos casos, por lo que esta sugerencia me parece una completa tontería e incluso dañina.
– RobertS apoya a Mónica Cellio
9 de junio de 2020 a las 16:23
@RobertSsupportsMonicaCellio no hay diferencia entre un espacio al frente o al final o en el medio, te equivocas al decir lo contrario. Si no recuerdo mal, quería cambiar el nombre para permitir encontrar esta pregunta más fácilmente.
– Stargateur
9 de junio de 2020 a las 17:23