我有以下代码
int myInt;
sscanf(str, "%d=%s", &myInt, str);
这会有效吗?如果我把它放在一个循环中,有没有更好的方法来做到这一点?
我的猜测是,这通常会起作用,因为源字符串似乎总是 >= 结果字符串,这似乎会导致确定性和指定的结果。
但我还是不会这样做。库函数通常具有restrict
-qualified 参数,以允许优化和预取。
不要诱惑编译器。
您可以利用 %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, <) == 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
解决此问题的一种方法是使用strtol
etc.,如果 number 为 > limit 则定义为将 value 设置为 type 和 set 的 MAX 值errno = ERANGE
。CStdLib.html#strtol