我们如何测试scanf()函数的返回值?

我想确认scanf()函数返回的值是否为浮点数。 我怎样才能做到这一点? 如果向scanf()函数提供了错误的数据类型,我的代码就不会运行。 同样,我如何确认返回的值是否是字符串?

scanf()等返回成功转换的次数。

如果你有:

 scanf("%f", &f); 

你应该测试:

 if (scanf("%f", &f) == 1) ...all OK... else ...EOF or conversion failure... 

如果您有多次转换,请检查它们是否已完成。 如果您正在使用%n ‘转换’,则不会计算它们。

尽管scanf()确实在EOF上返回EOF,但您不应该测试它 – 您应该始终检查您是否获得了预期的转换次数。 例如,考虑有缺陷的代码:

 while (scanf("%f %d %s", &f, &i, s) != EOF) // Here be BUGS! ...loop body... 

如果你键入3.14 x23 yes ,那么你将有一个无限循环,因为scanf()将在第一次迭代时返回1(它成功转换3.14),然后是0(不是EOF)。

你可能没问题:

 while ((rc = scanf("%f %d %s", &f, &i, s)) != EOF) { if (rc != 3) ...oops data problems... else ...all OK... } 

从以前的问题来看,您应该考虑使用fgets() (或可能是POSIX getline() )来读取数据行,然后使用sscanf()甚至strtol()strtod()strtol()来读取特定值这条线。 如果您使用sscanf() ,则上述有关检查成功转换次数的注释仍然适用。

我不在生产代码中使用scanf() ; 真是太难控制了。 我认为它几乎适合开始程序 – 除了它引起很多混乱。 总的来说,最好的建议是“远离scanf()fscanf() ”。 请注意,这并不意味着您必须避开sscanf() ,尽管使用sscanf()时仍需要谨慎。

scanf的返回值表示成功读取并分配给变量的项目数或EOF:

这些函数返回成功匹配和分配的输入项的数量,这可以少于提供的数量,或者在早期匹配失败的情况下甚至为零。

如果在第一次成功转换或匹配失败发生之前达到输入结束,则返回值EOF。 如果发生读取错误,也会返回EOF,在这种情况下,将设置流的错误指示符(请参阅ferror(3)),并设置errno指示错误。

如果scanf返回的int的值小于格式字符串中的输入说明符(或者至少需要传递参数的说明符)的数量,那么您可以假设出现了问题。

但是,如果要对浮点数进行更彻底的validation,则应考虑使用strtod() 。 即。 对于输入"1.23abc"scanf会将1.23存储到您的变量中并告诉您一切顺利,但是使用strtod可以检查转换的最后一个字符是否实际上是正在解析的字符串的结尾。