1

我有以下代码

int myInt;
sscanf(str, "%d=%s", &myInt, str);

这会有效吗?如果我把它放在一个循环中,有没有更好的方法来做到这一点?

4

2 回答 2

3

我的猜测是,这通常会起作用,因为源字符串似乎总是 >= 结果字符串,这似乎会导致确定性和指定的结果。

但我还是不会这样做。库函数通常具有restrict-qualified 参数,以允许优化和预取。

不要诱惑编译器。

于 2012-04-16T08:11:23.913 回答
3

您可以利用 %n 转换规范 -到目前为止读取的字符;需要 int* 参数CStdLib.html#fscanf

值得注意。标准说,大约%n

  • 不消耗任何输入。
  • 相应的参数应该是一个指向有符号整数的指针。
    • 到目前为止读取的字符数写入其中。
  • 不增加完成返回的分配计数。
  • 如果包含分配抑制字符或字段宽度,则行为未定义。

参考。ISO/IEC 9899:1999 §7.19.6.2

作为概念:

#include <stdio.h>
#include <string.h>

int main(void)
{
    int n;
    char *str = "12345=blabla 1313=blah "
                "333=hello 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee";
    char buf[15];
    int lt;

   /*                        +----- limit read to buffer length -1
                             |                +--- store read length here
                             |                |                        */
    while (sscanf(str, "%d=%14s%n", &n, buf, &lt) == 2) {
        fprintf(stdout,                   
            ":: '%s' :: \n"
            "Num: %d\n"
            "Str: %s\n"
            "Tot: %d bytes\n\n",
            str,
            n, buf,
            lt);
         str += lt;
    }

    return 0;
}

应该给出类似(过长的 %s 输入中断循环):

:: '12345=blabla 1313=blah 333=hello 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee' :: 
Num: 12345
Str: blabla
Tot: 12 bytes

:: ' 1313=blah 333=hello 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee' :: 
Num: 1313
Str: blah
Tot: 10 bytes

:: ' 333=hello 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee' :: 
Num: 333
Str: hello
Tot: 10 bytes

:: ' 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee' :: 
Num: 343
Str: goodbyeeeeeeee
Tot: 19 bytes

人们希望如何处理输入比缓冲区更长的时间可能很多。即检查是否有eof str,如果没有重新分配。从长度 = str 等的缓冲区开始。

请注意,数字 > INT_MAX 或 < INT_MIN 是未定义的行为 ()。使用“%d”规范时(通常?)会分别被截断为 INT_MAX 或 INT_MIN。

IE:

"1234533333333333333=blabla", read by "%d%s" =>

Num: 2147483647
Str: blabla
Tot: 26 bytes consumed

解决此问题的一种方法是使用strtoletc.,如果 number 为 > limit 则定义为将 value 设置为 type 和 set 的 MAX 值errno = ERANGECStdLib.html#strtol

于 2012-04-16T09:18:11.197 回答