我有以下代码
int myInt;
sscanf(str, "%d=%s", &myInt, str);
这会有效吗?如果我把它放在一个循环中,有没有更好的方法呢?
答案 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, <) == 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 = ERANGE
。 CStdLib.html#strtol