scanf("%f", &num);
我必须检查这是否是一个有效的浮点变量,如果它有@
或!
或%
等符号,则必须停止执行。
建议?
答案 0 :(得分:3)
检查scanf()
的返回值。它将返回成功扫描输入的数量 - 在您的情况下应该是1
。如果它不等于1,则它可以是-1,表示“文件结束”或0,表示“输入无效”。
答案 1 :(得分:3)
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 :(得分:2)
在scanf中使用%f说明符不会扫描任何其他内容,如果未指定浮点数,则不会读取任何内容。你应该检查scanf的返回值。
有一些定义的返回值:
EOF = -1
invalid input = 0
valid = >0
答案 3 :(得分:0)
您无法在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
注意:我没有检查代码,这是一个粗略的想法。
答案 4 :(得分:0)
您可以检查scanf()
的返回值。如果你看this page:
返回值
成功时,该函数返回成功填充的参数列表的项数。 由于匹配失败,阅读错误或文件结尾的影响,此计数可以与预期的项目数相匹配或更少(甚至为零)。
类似于:
if ( scanf( "%f", &num ) <= 0 )
{
// Stop the execution
}
// Continue
会做你想做的事。
答案 5 :(得分:0)
以文本形式阅读输入,然后使用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
是一个很好的工具。否则,最好使用上述方法。