sscanf - 如果遇到某些字符,请尽早停止扫描

时间:2018-02-09 07:14:53

标签: c scanf

我正在尝试扫描可能以“评论”结尾的字符串。

例如,假设我有以下字符串:

char *str = "first john last smith# example";

目前,我执行以下操作以从字符串中扫描我需要的内容:

  1. 删除评论+尾随空格(例如"first john last smith")。
  2. 扫描“修剪过的”字符串(例如,使用first %10s last %10ssscanf)。
  3. "john""smith"已成功扫描! :)
  4. 这样可行,但是如果遇到“#”,有没有一种标准方法可以避免通过让sscanf提前终止来修剪字符串?理想情况下,如果格式字符串相同,扫描"first john last smith""first john last smith# example"等字符串会产生相同的结果。

1 个答案:

答案 0 :(得分:1)

如果您有理由相信您不必处理不完整的信息(评论可能存在,但如果不存在则无关紧要),那么您只需阻止sscanf()解析带有'扫描集'的#符号,如下所示:

#include <stdio.h>

int main(void)
{
    char *str = "first john last smith# example";
    char fname[11] = "";
    char lname[11] = "";
    int rc = sscanf(str, "first %10[^# ] last %10[^ #]", fname, lname);

    printf("rc = %d, fname = [%s], lname = [%s]\n", rc, fname, lname);

    return 0;
}

该输出是:

rc = 2, fname = [john], lname = [smith]

如果评论字符出现在姓氏之前,那么您只能阅读john(除非它在此之前出现)。 sscanf()不需要担心尾随材料;它仍然存在于字符串中,但根本不需要查看它。

我赞同评论员认为这可能不是最可靠的工作方式。

请注意使用char fname[11];%10[…]来使字符串长度正常工作。一个接一个是令人讨厌的,但在标准的基础上,基于预先标准的传统是神圣的。如果你从头开始设计它,你就没有长度上的“一个一个”。还有一种方法可以动态指定字段长度,类似于%*.*f中的printf()表示法。遗憾的是,这不是由scanf()和朋友提供的。