【问题标题】:compare strings using sscanf, but ignore whitespaces使用 sscanf 比较字符串,但忽略空格
【发布时间】:2017-07-14 19:40:34
【问题描述】:

对于命令行应用程序,我需要将输入字符串与命令模式进行比较。空格需要忽略。

这一行应该匹配像“drop all”和“drop all”这样的输入字符串:

int rc = sscanf( input, "drop all");

但是这里的匹配成功是什么意思呢?

【问题讨论】:

  • 你似乎选择了错误的工具来完成这项工作......
  • @EugeneSh。也许吧,但有些命令也将数字等作为参数。所以这是一个没有参数的特殊情况。

标签: c scanf


【解决方案1】:

使用"%n" 记录扫描停止的位置。

将格式中的空格添加到input 中需要忽略的WS。

int n = -1;
sscanf( input, " drop all %n", &n);
//  v---- Did scanning reach the end of the format? 
//  |         v---- Was there additional text in `input`? 
if (n >= 0 && input[n] == '\0') Success();

【讨论】:

  • 老实说,如果没有问题中给出的要求,我无法理解这段代码在做什么。
  • 这是否适用于drop all 和`drop all`? (cmets 解析器好像坏了……)
  • @VTT:你为什么不试试呢?打字并不难,而且复制粘贴更容易。格式字符串中的空格匹配 0 个或多个空格字符——例如空格、制表符、换行符。而且 Markdown 使您很难使用反引号和空格(或其他反引号)获得您想要的结果。
  • @vtt 试试int n = -1; sscanf( "drop all", " drop all %n", &n); printf("%d\n", n); sscanf( " drop all ", " drop all %n", &n); printf("%d\n", n); 你会得到什么?
  • @EugeneSh。添加了一些cmets。 "%n"*scanf() 系列中非常有用的说明符。
【解决方案2】:

与其处理脏数据,不如先清理然后再处理它。清理只需要发生一次,而脏数据在每次使用时都会增加代码复杂性。此步骤通常称为“标准化”。在使用之前将输入规范化为规范形式。

通过修剪空白并执行任何其他必要的标准化(例如折叠和标准化内部空白)来清理输入。

您可以编写自己的修剪函数,但我建议您使用预先存在的函数,例如 Gnome Lib's g_strstrip()。 Gnome Lib 带来了各种方便的功能。

#include <glib.h>

void normalize_cmd( char *str ) {
    g_strstrip(str);

    // Any other normalization you might want to do, like
    // folding multiple spaces or changing a hard tab to
    // a space.
}

然后你可以在标准化输入上使用strcmp

// This isn't strictly necessary, but it's nice to keep a copy
// of the original around for error messages and such.
char *cmd = g_strdup(input);

normalize_cmd(cmd);

if ( strcmp(cmd, "drop all") == 0) {
    puts("yes");
}
else {
    puts("no");
}

将所有规范化放在前面可以降低所有下游代码必须使用该输入的复杂性;他们不必对脏数据重复同样的担忧。通过将所有规范化放在一个地方,而不是分散在所有代码中,您可以确定它是一致的,并且规范化方法可以持续更新。

【讨论】:

  • strcmp("drop\tall", "drop all") 将不匹配。通常,此类“清理”包括将多个 空白 转换为单个 ' ' 的过程。
  • @chux 当然。在处理数据之前进行任何额外的清理和规范化。
  • 这是一把两刃剑。建议的清理有利于后续处理,但原始输入对于日志记录和调试很有用。与任何用户输入一样,它是邪恶的,在经过审查之前不应使用。
  • 如果在结果中使用strlen() 来确定@​​987654329@....的可用空间,似乎trim_left() 可能会导致麻烦。
  • @DavidBowling 你没看评论吧。没有人阅读 cmets。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
  • 2016-07-09
相关资源
最近更新 更多