Ale*_*nze 5 c floating-point parsing scanf language-lawyer
每C标准从1999年,scanf()并strtod()应接受无穷大和NaN作为输入(如果实现支持)。
这两个函数的描述都有特殊的语言,可能会有不同的解释。
scanf():
输入项被定义为最长的输入字符序列,它不超过任何指定的字段宽度,并且是匹配输入序列或者是匹配输入序列的前缀。
strtod():
主题序列被定义为输入字符串的最长初始子序列,从第一个非空白字符开始,即预期形式。
虽然后一段摘录似乎严格要求“INF”、“INFINITY”、“NAN”或“NAN(n-char-sequence-opt)”的特定形式,但前者并非如此,人们会认为以下代码应产生无穷大和 NaN,因为字段宽度涵盖匹配输入序列的前缀:
int r;
double d;
d = 0; r = sscanf("inf", "%2le", &d);
printf("%d %e\n", r, d);
d = 0; r = sscanf("nan", "%2le", &d);
printf("%d %e\n", r, d);
Run Code Online (Sandbox Code Playgroud)
还有这一点scanf():
a,e,f,g 匹配可选的有符号浮点数、无穷大或 NaN,其格式与 strtod 函数的主题序列的预期格式相同。相应的参数应该是一个指向浮动的指针。
这是否只是未能证明比预期的最短形式(“inf”或“nan”)短的字段宽度 2 不会使其他匹配的前缀“in”和“na”有效匹配?
小智 2
无需记录此特定情况,因为它已包含在您对标准的引用之一中:
输入项被定义为最长的输入字符序列,该序列不超过任何指定的字段宽度,并且是匹配输入序列或者是匹配输入序列的前缀。
考虑这个简单的情况:
int ch;
int res;
const char *input_fmt;
ch = 0;
input_fmt = "%*d%c";
res = sscanf("123456789012345678901234567890abc", input_fmt, &ch);
printf("%d\t%c\n", res, ch);
// 1 a
Run Code Online (Sandbox Code Playgroud)
因为转换规范没有字段宽度%d,所以会匹配无限多个字符0-9,这就是ch=='a'扫描完成后的原因;的值n在这里并不重要。将其与使用以下命令的输出进行对比input_fmt="%*2d%c":
1 3
Run Code Online (Sandbox Code Playgroud)
第一个转换规范的字段宽度限制为 2 个字符,导致%c匹配3. 这就是“前缀”位出现的地方。12是 的前缀123456...,它与转换规范相匹配%d。另一个例子:
input_fmt = "%*2d%c";
res = sscanf("1a3456789012345678901234567890bc", input_fmt, &ch);
printf("%d\t%c\n", res, ch);
// 1 a
Run Code Online (Sandbox Code Playgroud)
字段宽度将匹配的字符数限制%d为 2,但匹配的输入序列的长度为 1,因为a不是十进制整数。
inf限制匹配输入的字段宽度是您的情况下发生的nan情况:
double d;
int r;
char s[10];
// 0 0.000000 ""
*s = 0; d = 0; r = sscanf("infinity", "%2le%9s", &d, s);
printf("%d\t%f\t\"%s\"\n", r, d, s);
// 2 inf "inity"
*s = 0; d = 0; r = sscanf("infinity", "%3le%9s", &d, s);
printf("%d\t%f\t\"%s\"\n", r, d, s);
// 0 0.000000 ""
*s = 0; d = 0; r = sscanf("-infinity", "%3le%9s", &d, s);
printf("%d\t%f\t\"%s\"\n", r, d, s);
// 2 -inf "inity"
*s = 0; d = 0; r = sscanf("-infinity", "%4le%9s", &d, s);
printf("%d\t%f\t\"%s\"\n", r, d, s);
Run Code Online (Sandbox Code Playgroud)
字段宽度限制了输入序列中的字符数,这可能会阻止识别特殊形式,例如-inf和。nan该行为已记录下来,但也无法立即完全理解。
| 归档时间: |
|
| 查看次数: |
1383 次 |
| 最近记录: |