Welche Wirkung haben nachgestellte Leerzeichen in einer scanf()-Formatzeichenfolge?

Lesezeit: 6 Minuten

Benutzer-Avatar
Vikas Verma

Was ist der Unterschied zwischen scanf("%d") und scanf("%d ") Wo ist in diesem Code der Unterschied das abschließende Leerzeichen in der Formatzeichenfolge?

#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;
}

Wie funktioniert die scanf() Funktion funktioniert tatsächlich, wenn ich Leerzeichen nach dem Formatbezeichner wie hinzufüge scanf("%d ", &j);?

  • Vielleicht sollten wir das Tittle umbenennen, um allgemeiner zu sein?

    – Sternengatter

    19. April 2018 um 4:13 Uhr

  • @Stargateur kannst du vorschlagen?

    – Vikas Verma

    23. April 2018 um 10:37 Uhr

  • Ich dachte daran, “Nachlauf” zu entfernen

    – Sternengatter

    23. April 2018 um 15:51 Uhr

  • @Stargateur Warum solltest du das tun wollen? Die Frage (und auch die Antworten) ist/sind eindeutig auf einen Formatstring mit fokussiert nachlaufend Leerraum, nicht führend eine (die natürlich von Vorteil sein kann und Gegenstand anderer SO-Fragen ist). Es gibt einen großen Unterschied zwischen den beiden Fällen, daher erscheint mir dieser Vorschlag als völliger Unsinn und sogar schädlich.

    – RobertS unterstützt Monica Cellio

    9. Juni 2020 um 16:23 Uhr


  • @Stargateur Es ist richtig, dass das tatsächliche Verhalten gleich ist, aber der tatsächliche Effekt hängt davon ab, wie Sie es verwenden. Überspringen von führenden Leerzeichen bis zur richtigen Eingabe wie " %c" oder am Konsum hängen (wie diese Frage zeigt). Damit gibt es auch einen Unterschied in der Bedeutung – nachlaufend Leerzeichen = immer schlecht; führender Leerraum = kann nützlich sein. – Ich weiß, worauf Sie hinweisen möchten, aber die Frage ist so gut, wie sie ist, und hat bereits Antworten, wie die Frage ist. Eine Änderung des Titels würde erfordern, dass auch die Antworten geändert werden müssten (mit Beispielen usw.).

    – RobertS unterstützt Monica Cellio

    9. Juni 2020 um 18:15 Uhr


Benutzer-Avatar
Chris Dodd

Ein Leerzeichen in einem scanf-Format bewirkt, dass es explizit so viele Leerzeichen wie möglich liest und ignoriert. Also mit scanf("%d ", ..., liest es nach dem Lesen einer Zahl weiterhin Zeichen und verwirft alle Leerzeichen, bis es ein Nicht-Leerzeichen in der Eingabe sieht. Dieses Nicht-Leerzeichen bleibt als nächstes Zeichen übrig, das von einer Eingabefunktion gelesen wird.

Mit deinem Code:

printf("enter a value for j ");

scanf("%d  ",&j);

printf("j is %d \n", j);

Es druckt die erste Zeile und wartet dann darauf, dass Sie eine Zahl eingeben, und dann warten Sie weiter auf etwas danach die Nummer. Also, wenn Sie nur tippen 5Eintreten, scheint es zu hängen – Sie müssen eine weitere Zeile mit einem Nicht-Leerzeichen eingeben, um fortzufahren. Wenn Sie dann eingeben 6Eintretendas wird der Wert für isodass Ihr Bildschirm in etwa so aussieht:

enter a value for j 5
6
j is 5
enter a value for i i is 6

Da die meisten Scanf-%-Konvertierungen auch führende Leerzeichen überspringen (alle außer %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

1379850cookie-checkWelche Wirkung haben nachgestellte Leerzeichen in einer scanf()-Formatzeichenfolge?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy