如何检查字符串包含有效的实数

时间:2017-04-05 09:13:03

标签: c command-line

我需要检查第二个命令行参数,看看它是否是一个有效的浮点数。

#include <stdio.h>
#include <math.h>

long int fact(int n)
{
    if (n >= 1)
        return n*fact(n - 1);
    else
        return 1;
}

double func(int x0, int n)
{
    int p = 2 * n + 1;

    return (double)pow(x0, p) / (double)fact(p);
}

double sinh_(int x0, int N)
{
    double sum = 0;
    int i = 0;
    for (i = 0; i <= N; i++)
    {
        sum = sum + func(x0, i);
    }

    return sum;
}

double err(int x0, int N)
{
    return abs(sinh(x0) - sinh_(x0, N));
}

int main(int argc, char**argv)
{
    double x0 = 0;
    int N = 0;

    printf("No of args %d\n", argc);

    //if CLA doesn't have exactly 4 arguments passed return -1
    //1st argument is app-name
    //2nd argument is x0
    //4th argument is N
    if (argc >= 3)
    {
        printf("Err: no of arguments should be 2");
        return -1;
    }
    //if the 2nd CLA is not a number, return -1     
    if (!isdigit(atof(argv[1])))
    {
        printf("1st argument must be a real value");
        return -1;
    }
    //if the 3rd CLA is not a number, return -1     
    if (!isdigit(atoi(argv[2])))
    {
        printf("2nd argument must be an int value");
        return -1;
    }

    x0 = atof(argv[1]);
    N = atoi(argv[2]);

    printf("Builtin sinh = %f", sinh(x0));
    printf("Approx sinh = %f", sinh_(x0, N));
    printf("Err value = %f", err(x0, N));
}

2 个答案:

答案 0 :(得分:2)

atof未返回状态以指示转化是否成功,您需要使用strtod。返回后检查endptrNULL,还检查是否有溢出或下溢。

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

char *end = NULL;
double x0 = strtod(argv[1], &end);
if (*end) {
      // error, not a valid floating point number
}
if (errno == ERANGE) {
     // error, overflow or underflow
}

答案 1 :(得分:1)

strto...系列函数(例如strtod将字符串转换为doublestrtol以将字符串转换为long int可以为您提供有关转换结束的字符串中的行踪的信息。

如果字符串不以可选空格开头,后跟有效数字,则它们将报告在字符串开头结束的转换。否则,他们将报告导致转换结束的角色的位置。因此,要检查错误,请检查位置是否已从字符串的开头“移动”,并检查报告的结束位置处的字符。

这些功能还会检查超出范围的值,将errno设置为ERANGE并返回特定值。

下面的代码检查字符串在数字后面是否以空终止符结尾,但在某些情况下,对于包含多个分隔值的字符串,您可能需要检查有效的分隔字符。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char **argv)
{
    double x0;
    long int N;
    char *endptr;

    if (argc != 3)
    {
        fprintf(stderr, "usage: %s x0 N\n", argv[0]);
        return 2;
    }

    errno = 0;
    x0 = strtod(argv[1], &endptr);
    if (endptr == argv[1] || *endptr != '\0')
    {
        fprintf(stderr, "1st argument must be a real value\n");
        return 2;
    }
    if (errno == ERANGE)
    {
        fprintf(stderr, "1st argument out of range\n");
        return 2;
    }

    errno = 0;
    N = strtol(argv[2], &endptr, 10);
    if (endptr == argv[2] || *endptr != '\0')
    {
        fprintf(stderr, "2nd argument must be an integer value\n");
        return 2;
    }
    if (errno == ERANGE)
    {
        fprintf(stderr, "2nd argument out of range\n");
        return 2;
    }

    printf("x0:%g; N:%ld\n", x0, N);
    return 0;
}

为方便起见,我将N的类型更改为long int,因为没有strtoi函数返回int