根据1999年的C标准,scanf()和strtod()应该接受无穷大和NaN作为输入(如果得到实现的支持)。
对这两种功能的描述有其独特的语言,可供解释。
scanf()
输入项被定义为不超过任何指定字段宽度的最长输入字符序列,它是或是匹配输入序列的前缀。
strtod()
主题序列被定义为输入字符串的最长初始子序列,从第一个非空白字符开始,即期望的形式。
虽然后一段似乎严格要求"INF“、”无穷大“、" NaN”或“NaN(n-char-序列-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);在scanf()上也有这样的一点
a,e,f,g匹配一个可选的有符号浮点数、无穷大或NaN,其格式与strtod函数的主题序列相同。相应的参数应该是一个指向浮动的指针。
这仅仅是没有记录到字段宽度2 (比预期的最短形式("inf“或"nan")更短)没有使其他匹配的前缀"in”和"na“有效匹配吗?
发布于 2017-06-04 13:55:30
没有必要记录这一特定情况,因为您从标准中引用的一个引号已经对此进行了介绍:
输入项被定义为不超过任何指定字段宽度的最长输入字符序列,它是或是匹配输入序列的前缀。
考虑一下这个简单的案例:
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因为%d转换规范没有字段宽度,所以它将匹配无穷多个字符0-9,这就是为什么扫描结束后的ch=='a';n的值在这里并不重要。与使用input_fmt="%*2d%c"的输出进行对比
1 3第一个转换规范的字段宽度限制为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字段宽度将匹配%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);字段宽度限制输入序列中的字符数,这可能会阻止识别-inf和nan等特殊形式。这种行为已被记录在案,但它也不能立即被完全理解。
https://stackoverflow.com/questions/44353361
复制相似问题