3

I saw somewhere a portion of code in C

char name[51];
int group = 0;
scanf("%*s %50s %*s %d", name, &group);
printf("%s / %d\n", name, group);

If we introduce

"Name:Smith Group:7"

it waits for us to introduce another values. It's strange. What is exactly happening and what does %*s %50s %*s mean. I saw %*s before but never put before and after reading a string.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261

1 Answers1

5

The * after the % and before the conversion specifier is an assignment suppression flag. It indicates that the matched entry will not be stored (.i.e., will be discarded) and a corresponding storage argument is not needed.

Quoting C11, chapter §7.21.6.2

[...] Unless assignment suppression was indicated by a *, the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result.

That said, for the input

Name:Smith Group:7

what you expect is something like

  • %*s matches "Name:" and discards
  • %50s matches "Smith" and stores
  • %*s matches "Group:" and discards
  • %d matches 7 and stores.

However, there is a problem. For the conversion specifier s,

Matches a sequence of non-white-space characters

That means, it'll scan and match until a whitespace, and since there's no whitespace till before "Group", the whole "Name:Smith" will be consumed by the first %*s directive. Same happens for the following %*s, also. Thus, the conversion specification does not conclude, and scanf() waits for the next input to be consumed.

So, to match the conversion specification, supply the input as

Name: Smith Group: 7
     ^^           ^^
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261