sscanf 会返回正确数量的参数,即使最后一个输入错误

问题描述 投票:0回答:3

所以我有这部分代码用于从字符串中读取一些信息:

  fgets(line, sizeof(line), stdin);
  ...
  else if((sscanf(line, "%s %s %lf %d ", name, id, &price, &qnt ) != 4) ||
                                                    (strlen(name) > 49) || 
                                                    (strlen(id) > 4)){
 ...

问题是当我插入这样的输入时:

somename 123A 12 12a

这是一个错误的输入,因为

12a
不是
int
sscanf
返回 4,因此执行继续。

如果我插入这样的输入:

somename 123A 12a 123

效果很好。

有什么解决方法可以解决这个问题吗?感谢您的宝贵时间:)

c scanf
3个回答
2
投票

您可以这样用

sscanf
解析字符串:

char name[50];
char id[5];
double price;
int qnt;
char c;
if (sscanf(line, "%49s%4s%lf%d %c", name, id, &price, &qnt, &c) != 4) {
    // invalid input
}
  • 如果其中一个字段无法解析,则返回值将小于4。
  • 如果末尾有多余的输入,
    %c
    将跳过尾随空格并成功将多余的字符转换为
    c
    ,返回值为
    5

1
投票

您收到的输出是正确的。这是 sscanf() 函数的标准行为。您需要了解的是 scanf() 是一个模式匹配函数,而不是读取多个参数的函数(尽管它也这样做)。

例如,

scanf("[%d][%d][%d]", &a, &b, &c)

预计输入格式为 [10][20][30]

scanf() 的工作原理是,它一次读入一个字符,尝试将其与模式进行匹配,当违反模式时,将收到的值放入相应的变量中,然后放回额外的字符(违反模式的字符) )回到输入流。

因此,在您的情况下,当您输入以下内容时:

somename 123A 12 12a

最后的12a将被逐个字符地处理,当遇到a时,它将把接收到的值放到该时刻(12)并将其放入指定的变量中。


0
投票

我最近发现了一种我以前从未见过的格式规范。它为N'。它返回的是到该点处理的字符数。您可以使用它作为最终说明符,如果没有处理到该点的所有字符,它将返回 -1。

sscanf(line, "%s %s %lf %d%n", 名称, id, &price, &qnt, &charsScanned ); if (charsScanned > 0) {...} // 有效输入

虽然我也很喜欢上面chqrlie的解决方案!

© www.soinside.com 2019 - 2024. All rights reserved.