¿Cuál es el efecto de los espacios en blanco finales en una cadena de formato scanf()?

6 minutos de lectura

avatar de usuario
Vikas Verma

¿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);?

  • ¿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

avatar de usuario
chris dodd

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 ipor 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.

  • So the reason why it hangs until next non-white space character is because that it wants to make sure that “ok, that’s all (lumped) white space I can match”?

    – mzoz

    Jul 9, 2017 at 18:12

user avatar
haccks

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.

  • Will it actually terminate on a posix system where that command backgrounds the top process?

    – Cloud

    Oct 21, 2013 at 16:09

  • @Dogbert; Not sure but for MS-WIN: Ctrl + D

    – haccks

    Oct 21, 2013 at 16:13


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.

  • This doesn’t make the key point clear — that scanf() won’t return until something that isn’t white space is entered. That, in turn, means you have to guess what the program is going to ask next and enter the next value before the current input completes. (If you don’t enter the complete next value, then you’ll have more problems; the odd one character (and the newline that must follow before the terminal sends the character to the program) will be interpreted as the next field. Trailing spaces in interactive formats are dire!

    – Jonathan Leffler

    Sep 15, 2015 at 15:04

user avatar
Cloud

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad