C - 可以sscanf读取它写入的相同字符串吗?

时间:2012-04-16 07:57:08

标签: c string

我有以下代码

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

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

2 个答案:

答案 0 :(得分:3)

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

但我仍然不会这样做。库函数通常具有restrict个限定参数,以便进行优化和预取。

不要试探编译器。

答案 1 :(得分: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是否重新分配。从length = str等的缓冲区开始。

注意数字&gt; INT_MAX或&lt; INT_MIN是未定义的行为()。使用“%d”规范时,Will(通常是?)会分别截断为INT_MAX或INT_MIN。

I.e。:

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

Num: 2147483647
Str: blabla
Tot: 26 bytes consumed

解决此问题的一种方法是使用strtol等,如果数字是&gt; limit定义为将值设置为MAX值并设置errno = ERANGECStdLib.html#strtol