1
scanf("%f", &num);

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

建议?

4

6 回答 6

3

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

于 2013-08-13T13:29:32.017 回答
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 */
}
于 2013-08-13T14:06:19.100 回答
2

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

有几个定义的返回值:

EOF = -1
invalid input = 0
valid = >0
于 2013-08-13T13:29:11.217 回答
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当您知道您的输入格式正确时,这是一个很好的工具;否则,最好使用上述方法。

于 2013-08-13T15:09:47.190 回答
0

您可以从中检查返回值scanf()。如果您查看此页面

返回值

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

所以像:

if ( scanf( "%f", &num ) <= 0 )
{
    // Stop the execution
}
// Continue

会做你想做的。

于 2013-08-13T13:50:23.497 回答
0

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

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

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

于 2013-08-13T13:46:22.777 回答