如何检查输入是否为数字(浮点型)或某些字符?

时间:2019-01-16 05:14:20

标签: c floating-point

在我的大学里,我被要求编写一个程序来查找两个输入的总和,因此我应该首先检查输入是否有效。

例如,如果我输入了2534.11s35,则该程序应检测到由于该输入中的s,因此它不是该程序的有效输入。

4 个答案:

答案 0 :(得分:2)

  

检查输入是否为数字(浮点数)

1)将输入作为字符串char buf[Big_Enough]。我希望160位数字可以处理除最不可思议的“浮动”字符串之外的所有字符串 1

#define N 160
char buf[N];
if (fgets, buf, sizeof buf, stdin) {

2)将float strtof()应用于float,(将strtod()应用于double,将strtold()应用于long double)。

  char *endptr;  
  errno = 0;
  float d = strtof(buf, &endptr);
  // endptr now points to the end of the conversion, if any.

3)检查结果。

    if (buf == endptr) return "No_Conversion";
    // Recommend to tolerate trailing white-space.
    //   as leading white-spaces are already allowed by `strtof()`
    while (isspace((unsigned char)*endptr) {
      endptr++;
    }
    if (*endptr) return "TrailingJunkFound";
    return "Success";

4)如果需要,进行极端测试。

此时,输入为数字。问题仍然存在,即“有限字符串”是否可以由有限的float表示:如果| result |处于0[FLT_TRUE_MIN...FLT_MAX]的范围内。

这涉及查看errno

float范围之外的转换“成功”但有限的字符串值变为HUGE_VALF,可能是无穷大或FLT_MAX

Wee |值|接近0.0,但不等于0.0会变成[0.0 ... INT_MIN]范围内的值。

由于目标是检测转换是否成功(确实如此),因此我将这些细节留给一个问题,以期深入了解的含义。


一种替代方法是使用fscanf()直接读取和转换,但是那里的错误处理也有麻烦,并且难以移植。


1 Typical float的范围是+/- 10 38 。因此,允许40个左右的字符是有意义的。精确打印FLT_TRUE_MIN 大约需要150个字符。要从另一个较大的FLT_TRUE_MIN中区分出一个任意“浮点”字符串,需要大约几个数字。

如果“浮动”字符串不是任意的,而是仅来自打印的float的输出,则需要很少的数字-大约40。

当然,允许额外的前导/尾随空格和零是明智的。

答案 1 :(得分:1)

您需要将输入作为 string ,然后使用strtod()来解析输入。

关于返回值,来自man page

double strtod(const char *nptr, char **endptr);
     

这些函数返回转换后的值(如果有)。

     

如果endptr不为NULL,则指向转换中使用的最后一个字符之后的字符的指针将存储在endptr所引用的位置。

     

如果不执行任何转换,则返回零,并将nptr的值存储在endptr所引用的位置。

到达错误检测点,有几点:

  • 确保在通话前将errno设置为0,并在通话后仍将其设置为0
  • 返回值不是HUGE_VAL
  • *endptr指向的内容不为空且不等于nptr(即未进行任何对话)。

以上检查结合在一起将确保成功转换。

在您的情况下,最后一点很重要,就像输入中存在无效字符一样,*endptr不会指向空,而是保留该地址(第一个)输入的字符无效。

答案 2 :(得分:0)

#include<stdio.h>
#include<stdlib.h>
void main(){
char num1[15];
float number1;
int dot_check1=0,check=0,i;
printf("enter the numbers :\n");
gets(num1);
i=0;
while(num1[i]){
    if(num1[i]>'/' && num1[i]<':')
        ;
    else { if(dot_check1==0){
            if(num1[i]=='.')
                dot_check1=1;
            else {
                check=1;
                break;
                }
            }
            else  {
                check=1;
                break;
                }
        }
    i++;
}
if(check){
    printf("please check the number you have entered");
}
else{
    number1=atof(num1);
    printf("you entered number is %f",number1);
}
}

答案 3 :(得分:0)

这是未经测试的代码,用于检查字符串是否符合要求的规范。

#include <ctype.h>


/*  IsFloatNumeral returns true (1) if the string pointed to by p contains a
    valid numeral and false (0) otherwise.  A valid numeral:

        Starts with optional white space.
        Has an optional hyphen as a minus sign.
        Contains either digits, a period followed by digits, or both.
        Ends with optional white space.

    Notes:

        It is unusual not to accept "3." for a float literal, but this was
        specified in a comment, so the code here is written for that.

        The question does not state that leading or trailing white space
        should be accepted (and ignored), but that is included here.  To
        exclude such white space, simply delete the relevant lines.
*/
_Bool IsFloatNumeral(const char *p)
{
    _Bool ThereAreInitialDigits = 0;
    _Bool ThereIsAPeriod = 0;

    //  Skip initial spaces.  (Not specified in question; removed if undesired.)
    while (isspace(*p))
        ++p;

    //  Allow an initial hyphen as a minus sign.
    if (*p == '-')
        ++p;

    //  Allow initial digits.
    if (isdigit(*p))
    {
        ThereAreInitialDigits = 1;
        do
            ++p;
        while (isdigit(*p));
    }

    //  Allow a period followed by digits.  Require at least one digit to follow the period.
    if (*p == '.')
    {
        ++p;
        if (!isdigit(*p))
            return 0;
        ThereIsAPeriod = 1;
        do
            ++p;
        while (isdigit(*p));
    }

    /*  If we did not see either digits or a period followed by digits,
        reject the string (return 0).
    */
    if (!ThereAreInitialDigits && !ThereIsAPeriod)
        return 0;

    //  Skip trailing spaces.  (Not specified in question; removed if undesired.)
    while (isspace(*p))
        ++p;

    /*  If we are now at the end of the string (the null terminating
        character), accept the string (return 1).  Otherwise, reject it (return
        0).
    */
    return *p == 0;
}