c语言 - 为什么 scanf 接受"%f"格式说明符的字符?



我正在为我的类准备一个简单的程序,发现scanf没有我预期的那么严格:

int main()
{
// Define variables
float alpha;
float b;
float result;
// Get user input
printf("Type alpha and b. Space separated float numbers only.n");
scanf("%f %f", &alpha, &b);
printf("%f %fn", alpha, b);
return 0;
}

退货:

Type alpha and b. Space separated float numbers only.
a 0
-29768832.000000 0.000000

我在哪里可以了解它的行为?

如果既没有int也没有float,我如何使输入严格遵守标准函数并抛出异常?

第页。S.我在Ubuntu中使用gcc v5。

我正在为我的类准备一个简单的程序,发现scanf没有我预期的那么严格

不,你没有。

给定此scanf调用:

float alpha;
float b;
scanf("%f %f", &alpha, &b);

。。。这个输入:

a 0

。。。scanf在尝试扫描浮点值但尚未扫描任何十进制数字时遇到"a"时,会出现匹配失败。它在该点停止(并在流中留下"a"以供后续读取(,并且一如既往地,它返回成功扫描的输入字段数(0(。

在哪里可以了解它的行为?

您可以尝试在命令行(Linux、OSX…(运行命令man scanf,或者输入与Google搜索相同的命令。或者谷歌"scanf文档"或"scanf手册"或类似内容。或者查找特定C库的官方手册。对于标准库函数,该标准是一个很好的参考,但您的特定实现可能有没有记录的扩展,或者偶尔可能与标准有细微的不同。

如何使输入严格遵守标准函数并抛出如果既没有int也没有float,则异常?

C没有例外。在大多数情况下,它通过函数返回值告诉您有关错误的信息,尽管一些第三方库可能会做得稍有不同。但是,您必须通过检查返回值并做出适当的响应来完成您的部分。在这种特殊情况下,必须避免读取alphab的值。因为这些变量没有初始化,随后也没有任何值分配给它们,所以读取它们的值会产生未定义的行为

其他人的回答,特别是@John Bollinger很好地解释了代码未能达到目标的原因。

音符输入可以转换为intfloat、两者都不转换或两者都转换。

如果既没有int也没有float,我如何使输入严格遵守标准函数并抛出异常?

最好使用fgets()等其他工具来读取输入的,并形成字符串以供稍后测试。

严格测试有点困难。*scanf("%d",...)在溢出时有未定义的行为*scanf("%f",...)具有类似的UB,特别是当float不支持无穷大/非数字时。


测试字符串是否转换为有效的int

bool my_isint(const char *s) {
// Add to dis-allow leading white-space
if (isspace((unsigned char) *s)) return false;
char *endptr; 
base = 0; // use base = 0 to only allow base 10 input
errno = 0;
long val = strtol(s, &endptr, base); 
if (s == endptr) return false; // no conversion
if (errno == ERANGE) return false; // too big for long
if (val > INT_MAX || val < INT_MIN) return false; // too big for int
// Add to allow trailing white-space
while (isspace((unsigned char) *endptr)) endptr++;
// Add to dis-allow trailing junk
while (*endptr) return false; // trailing junk
return true;
}

float支持无穷大/非数字时,测试字符串是否转换为有效的float就像测试double一样。稍后介绍-GTG。

@John Bollinger(answer(和@chux(answere(善意地解释了这个问题本身是错误的,实际上scanf不接受字符而不是浮点,但省略了它。为了捕捉这种行为,我以以下方式修改了代码:

+ #include <errno.h> // Error codes constants
int main()
{
// Define variables
float alpha;
float b;
+ int matches;
float result;
// Get user input
printf("Type alpha and b. Space separated float numbers only.n");
± matches = scanf("%f %f", &alpha, &b);
+ if (matches != 2) {
+   printf("ERROR: Space separated float numbers only expected.n");
+   return EINVAL;
+ }
printf("%f %fn", alpha, b);
return 0;
}

仅适用于您在CS学位期间编写的简单学习程序

否则,请查看@chux的答案,以获得更像生产的解决方案。

最新更新