检查输入是不是浮动,否则停止

Posted

技术标签:

【中文标题】检查输入是不是浮动,否则停止【英文标题】:Check if input is float else stop检查输入是否浮动,否则停止 【发布时间】:2013-08-13 13:26:32 【问题描述】:
scanf("%f", &num);

我必须检查这是否是一个有效的浮点变量,如果它有 @!% 等符号,则停止执行。

建议?

【问题讨论】:

man page for scanf 说明它的返回值表示它匹配的值的数量。在您的情况下,如果 num 已设置为有效的 float,则该值为 1 标题中不需要写“In C”,标签已经写好了。 您是否正在寻找一行上的有效浮点数?因为scanf 如果找到一个浮点数,但即使它后面有“东西”,它也会成功检索浮点数。例如,scanf("%f", &num) 将从3.2@#$$% 等输入返回1(读取的浮点数),将3.2 的值放入num。当它到达@ 时,它就会停止读取。如果您需要扫描“东西”以到达下一个浮点数,您将需要一种机制,因为scanf("%f"...) 只会坐在那里,在随后的调用中停留在@,返回0,除非你做别的事。 您应该举例说明哪些输入将被接受和拒绝(如果有)。或者通常你希望你的程序在给定一堆输入的情况下做什么。 (“停止执行”是否意味着您的程序应该退出并显示错误消息?或者scanf() 应该停止扫描?)scanf()strtol() 都不执行“验证”,即它们将接受任何以 a 开头的字符串浮动。 【参考方案1】:

scanf 不是你的朋友,在这里。即使您检查结果 确保您成功阅读了一个完整的论点,这不会 真正保证输入在有意义的意义上是有效的。

给定输入:

1!!!1!oneone!

%f 解析将在读取第一个 1 后停止(但成功), 并将读取指针留在以下!。这可能不是什么 您认为“有效输入”。

在这种情况下,请尝试:

if (scanf("%f%c", &f, &c) == 2 && isspace(c))
    /* success */

但是,这将接受以下内容:

1 oneoneonespace!bang

如果同一行中的任何内容都被视为垃圾,那么它会得到 困难,因为scanf 不区分空格和 换行符。也许尝试这样的事情:

char buffer[1024];
if (fgets(buffer, sizeof(buffer), stdin) != NULL)

    if (sscanf(buffer, "%f %c", &f, &c) == 1)
        /* success */

【讨论】:

【参考方案2】:

检查来自scanf() 的返回值。它将返回成功扫描输入的数量 - 在您的情况下,它应该是 1。如果不等于 1,则可能是 -1,表示“文件结束”或 0,表示“输入无效”。

【讨论】:

【参考方案3】:

在 scanf 中使用 %f 说明符不会扫描任何其他内容,如果没有指定浮点数,则不会读取任何内容。你应该检查scanf的返回值。

有几个定义的返回值:

EOF = -1
invalid input = 0
valid = >0

【讨论】:

【参考方案4】:

您无法在scanf 中检查您的两个条件。我建议将整个输入读入一个字符串,寻找特殊字符。一旦此测试通过,请尝试通过sscanf 将其重新处理为字符串。 要搜索特殊字符,在string.h 中定义了一个strpbrk

char* specials = "%@!";
char* buffer[SOME_SIZE];
double value;
int err;

scanf("%s", buffer);
if( strpbrk(buffer, specials) ) return SPECIAL_FOUND;
err = sscanf(buffer, "%f", &value);
if(err <= 0) return NOT_VALID_INPUT; //NOTE: there should probably be not EOF case

// process your value

注意:我没有检查代码,这是一个粗略的想法。

【讨论】:

strtof() 更好,因为它会告诉它停止解析的位置,您可以使用它来检查 \0【参考方案5】:

您可以检查来自scanf() 的返回值。如果你看this page:

返回值

成功时,函数返回参数列表中成功填充的项目数。 由于匹配失败、读取错误或到达文件末尾,此计数可能与预期的项目数匹配或更少(甚至为零)

类似:

if ( scanf( "%f", &num ) <= 0 )

    // Stop the execution

// Continue

会做你想做的。

【讨论】:

【参考方案6】:

将您的输入读取为文本,然后使用strtod 库函数将其转换;这允许您检查输入是否包含任何无效字符:

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
...
char buf=[81];
double result = 0.0;
...
if ( fgets( buf, sizeof buf, stdin ) != NULL )

  char *chk;
  double tmp = strtod( buf, &chk );
  if ( isspace( *chk ) || *chk == 0 )
    result = tmp;
  else
    fprintf( stderr, "%s is not a valid floating-point number\n", buf );

在调用strtod 之后,变量chk 将指向字符串中不属于有效浮点常量的第一个字符。如果这个字符是空格或 0,那么你很好;否则你有错误的输入。

这种方法相对于scanf 的优势在于,如果您的输入仅以一个有效字符开头(例如"1blkjhsdf"),它将转换并分配"1" 并返回一个1,表示转换成功,即使您可能想要拒绝该输入。它还消耗整个输入字符串(假设输入缓冲区足够大),因此它不会在输入流中留下任何垃圾来破坏下一次读取。

scanf 是一个很好的工具,当您知道您的输入格式正确时可以使用;否则,最好使用上述方法。

【讨论】:

以上是关于检查输入是不是浮动,否则停止的主要内容,如果未能解决你的问题,请参考以下文章

检查输入的值是不是存在 IF 是 防止保存 否则

检查用户输入是不是包含子字符串

如何检查 Java 程序的输入/输出流是不是连接到终端?

文本输入突然停止在 Kivy 应用程序中工作

检查输入字段中的空值的正确方法是啥[重复]

如何检查oracle监听是不是打开