【问题标题】:Match zero or more spaces using sscanf使用 sscanf 匹配零个或多个空格
【发布时间】:2014-12-22 23:28:37
【问题描述】:

让我们拥有这段代码

char input[] = "key: value";
char key[32], value[32];
sscanf(input, "%31[^:]:%*[ ]%31s", key, value);

: 之后可以有零个或多个空格,我想将键值存储到 c 字符串变量中。上面的代码可以使用一个或多个空格,但如果使用零个空格就很不幸了。

有没有一种简单的方法来解析这些字符串?不一定是 sscanf,但我想避免使用正则表达式。

编辑

我发现reference 支持已接受的答案(多么有用但不直观的功能):

该函数将读取并忽略任何空白字符 在下一个非空白字符(空白 字符包括空格、换行符和制表符——参见 isspace)。 格式字符串中的单个 空格可验证任意数量的 从流中提取的空白字符不包括)。

【问题讨论】:

  • @PaulRoub:情况是相关的,但我认为这与可能的重复不同。特别是,这个问题有一个简单的解决方案;我认为在另一个问题中没有“必要时尝试两次”答案的替代方法。
  • 我建议使用 strstr 查找 ':' 将 ':' 替换为 '\0' 然后 strncpy() 来获取第一个字符串。然后使用先前获取的 ptr 到 '\0',前进到下一个非 '' 字符,然后可能 sscanf() 来检索第二个字符串。另一种方法是使用 strtok()

标签: c string parsing scanf


【解决方案1】:

只需使用"%31[^:]:%31s"

%s 转换规范无论如何都会跳过前导空格,并在一个或多个非空格后的第一个空格处停止。

如果您决定在第二个字段中需要空格,而不是前导空格,请使用:

"%31[^:]: %31[^\001]"

(假设您的字符串不太可能包含您感兴趣的 control-A 字符)。格式字符串中的空格会跳过零个或多个空格(严格来说是零个或多个空格字符)。

【讨论】:

  • 正是我想要的。我不敢相信我不知道这一点。
  • 我认为这是使用否定扫描集后的简单疏忽或过度思考。 :D 有时,它只需要第二个人来看看(尽管有 cmets 表示其他人也不确定)。 scanf() 系列函数非常微妙。他们不容易掌握。至少你在使用sscanf();这更容易处理,因为如果第一次尝试失败,您可以返回并使用第二个格式字符串重试(并且您可以在任何错误消息中使用该字符串,而不仅仅是碎片)。 scanf() 和其他文件读取变体无法做到这一点。
  • "%31[^:]: %31[^\0]"
  • @user3386109:我在回答时曾短暂地想知道 ("%31[^:]: %31[^\0]"),但使用它意味着您将格式错误的扫描设置为 sscanf() 作为格式字符串,它这就是为什么我用\001 代替\000(又名\0)。我认为使用\\0 也行不通。 sscanf() 无法读取超出第一个空字节的格式字符串,即使空字节位于扫描集的中间——与“指针加长度”表示法相比,C 的空终止字符串的一个缺点。
  • 啊,你是对的。 \0 只是在该点终止字符串。所以它似乎在快速测试中工作,但它并没有像我想象的那样工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多