首页 > 解决方案 > C %*s 中的字符串格式

问题描述

我在某处看到了 C 中的一段代码

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

如果我们介绍

“名称:史密斯组:7”

它等待我们引入另一个值。真奇怪。到底发生了什么,%*s %50s %*s意味着什么。我%*s之前看过,但从未在阅读字符串之前和之后放置过。

标签: cstringinputprintfconversion-specifier

解决方案


转换说明符*之后%和之前是分配抑制标志。它表示匹配的条目将不会被存储(即,将被丢弃)并且不需要相应的存储参数。

引用C11,第 7.21.6.2 章

[...] 除非由 a 指示分配抑制,否则*转换结果将放置在尚未收到转换结果的格式参数之后的第一个参数所指向的对象中。

也就是说,对于输入

Name:Smith Group:7

你期望的是类似的东西

  • %*s匹配“名称:”并丢弃
  • %50s匹配“Smith”和商店
  • %*s匹配“组:”并丢弃
  • %d比赛7和商店。

但是,有一个问题。对于转换说明符s

匹配一系列非空白字符

这意味着,它将扫描并匹配直到出现空格,并且由于在“Group”之前没有空格,因此整个“Name:Smith”将被第一个%*s指令使用。以下情况%*s也一样。因此,转换规范没有结束,而是scanf()等待下一个输入被消费。

因此,要匹配转换规范,请将输入提供为

Name: Smith Group: 7
     ^^           ^^

推荐阅读