检查输入是不是浮动,否则停止
Posted
技术标签:
【中文标题】检查输入是不是浮动,否则停止【英文标题】:Check if input is float else stop检查输入是否浮动,否则停止 【发布时间】:2013-08-13 13:26:32 【问题描述】:scanf("%f", &num);
我必须检查这是否是一个有效的浮点变量,如果它有 @
或 !
或 %
等符号,则停止执行。
建议?
【问题讨论】:
man page forscanf
说明它的返回值表示它匹配的值的数量。在您的情况下,如果 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
是一个很好的工具,当您知道您的输入格式正确时可以使用;否则,最好使用上述方法。
【讨论】:
以上是关于检查输入是不是浮动,否则停止的主要内容,如果未能解决你的问题,请参考以下文章