【问题标题】:C: sscanf assignment suppression and the return valueC:sscanf赋值抑制和返回值
【发布时间】:2012-04-14 04:22:19
【问题描述】:

我正在尝试在 C 中使用 sscanf 从字符串中获取一些值。但是,如果字符串的值比我想要的多,我需要它来引发错误。 IE。如果我想要一个整数,“2”应该没问题,但“2 5”应该崩溃。

现在像这样使用 sscanf 上的返回值:

if (sscanf(mystring, "%d %*s", &num) == 1)

不起作用,因为即使字符串更长,它也会返回 1。我可以这样做:

char tmpString [100];
if (sscanf(mystring, "%d %s", &num, tmpString) == 1)

效果很好,但不是特别好。还有其他方法吗?我可以使用赋值抑制,仍然得到我想要的返回值吗?

编辑 这是我使用的代码:

char c; // This is a global variable, just gets used over and over.
sscanf(mystring, "%d%c", &num, &c);
    if (c == '\n') {

【问题讨论】:

  • 我通常这样做:char c; if (sscanf(mystring, "%d%c", &num, &char) == 1)
  • 好吧,如果你只想让它崩溃,你可以使用:sscanf(mystring, "%d %d", &num1, &num2); (=
  • 谢谢贾里德。我猜与我的代码相同,但只使用一个字符更有效。效果很好。
  • 在您的特定情况下,您可以使用strtol,然后检查结束指针是否为\0
  • 关于您选择的解决方案,我会谨慎地重复使用c,因为如果它读取一次'\n',但下一次调用无法读取任何内容,则不一定清楚它失败了,因为它的值仍然是'\n'。使用局部变量并将其初始化为 0 不会对性能产生明显影响,并且可以完全避免该问题。

标签: c scanf


【解决方案1】:

一种可能性是:

int pos;
if (sscanf(mystring, "%d %n", &num, &pos) == 1)
{
    if (mystring[pos] != '\0')
        ...oops...extra data...
    else
        ...only number...
}
else
    ...not even one number...

%n 是 C89 的一部分。它不是一个特别常用(或广为人知)的转换规范。它不被计为一次转化(因此测试1)。

【讨论】:

  • 谢谢。这似乎比上面 Jared 的代码:char c; if (sscanf(mystring, "%d%c", &num, &char) == 1) 复杂得多。有什么好处吗?
  • 您的选择;它并不是那么复杂,并且当数字后面只有空格(空白)时不会抱怨,而如果数字后面有空格或换行符,Word Like Jared 的代码会给你一个错误。当然,这取决于你想要什么。 %n 还允许您在数字末尾之后开始扫描,如果这是您想要的(可能不在这种情况下)。
  • 好的,谢谢。我混合使用了您的代码和 Jared 的代码,因为如果数字后有空格,我需要它来抛出错误,但如果有换行符则不会。我已将代码放在 OP 的末尾。
【解决方案2】:

一个更简单的测试,只使用scanf返回值而不是一个返回值和一个字符计数的测试,是可能的:

if (1 == sscanf(mystring, "%d %c", &num, &(char){0}))

这是有效的,因为如果在尾随空格被消耗后有任何字符,则执行第二次赋值,因此返回值是 2 而不是 1。

(char){0} 是一个复合文字,它提供了一个临时对象来保存分配的char,之后它被丢弃。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 2017-07-24
    • 2014-10-12
    • 1970-01-01
    • 2012-06-16
    • 2018-10-16
    • 2016-07-26
    相关资源
    最近更新 更多