代码之家  ›  专栏  ›  技术社区  ›  Vasudha Dixit

*指针变量!='\0'不适用于strtol()函数中转换失败的检查

c
  •  0
  • Vasudha Dixit  · 技术社区  · 6 年前

    程序无法进行输入 5r 即在输入中,当第一个字符是数字,而下一个字符是任何字母或负数时。例如,当我在输出中输入为5R时,得到的是5的阶乘。

    所以我试着检查 strtol 转换失败:

    if (p == buf || *p != '\0'){ printf("\nInvalid input: not a number\n");}
    

    但我得到的输出是 Invalid input: not a number 所有的输入。

    我在堆栈溢出中发现了许多类似的问题。但是,他们没有解决我的问题。我不明白这张简单的支票怎么了?如何成功检测错误 斯特罗尔 ?

    #include <stdio.h>
    #include <limits.h>
    #include <stdlib.h>
    #include <errno.h>
    
    int display();
    void fact_fun(int num_fact);
    
    int main()
    {
        int num;
        while ((num = display()) >= 0)
            {
            fact_fun(num);
            }
        return 0;
    }
    
    int display()
    {
        char buf[256];
        char *p;
        long value;
    
    
        for (;;)
            {
            printf("\nEnter number to find factorial or press ENTER KEY to exit: ");
    
            if (fgets(buf, sizeof buf, stdin) == NULL || *buf == '\n')
                return -1;
    
            errno = 0;
            value = strtol(buf, &p, 0);
    
            if (p == buf || *p != '\0')
                {
                printf("\nInvalid input: not a number\n");
                }
            else
                {
                if (value < 0)
                {
                    printf("\nInvalid input: negative values not allowed\n");
                }
                else if (errno != 0 || value > INT_MAX)
                    {
                        printf("\nInvalid input: value too large for type int\n");
                    }
                    else
                        {
                            return (int)value;
                        }
                }
            }
    }
    
    void fact_fun(int num_fact)
    {
        int fact = 1;
        for (int i = 1; i <= num_fact; i++)
            {
            if (fact > INT_MAX / i)
            {
                printf("\nInvalid input: arithmetic overflow\n");
                return;
            }
            fact = fact * i;
        }
        printf("\nFactorial of %d is %d\n", num_fact, fact);
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Fuel    6 年前

    你得到的绳子 fgets 包含 '\n' 作为最后一个字符,因为您点击了Enter,所以将其替换为 '\0' . 这是C编码器有时会犯的一个常见错误。

    编辑: 所以我自己测试过,你是对的,原因是strtoi没有搞乱线路终结者,所以现在它可以通过以下检查工作了:

    *p != '\n' 
    

    完整的工作代码如下:

    #include <stdio.h>
    #include <limits.h>
    #include <stdlib.h>
    #include <errno.h>
    
    int display();
    void fact_fun(int num_fact);
    
    int main()
    {
        int num;
        while ((num = display()) >= 0)
            {
            fact_fun(num);
            }
        return 0;
    }
    
    int display()
    {
        char buf[256];
        char *p;
        long value;
        for (;;)
            {
            printf("\nEnter number to find factorial or press ENTER KEY to exit: ");
            if (fgets(buf, sizeof buf, stdin) == NULL || *buf == '\n')
                return -1;
            errno = 0;
            value = strtol(buf, &p, 0);
            if (p == buf || *p != '\n')
                {
                printf("\nInvalid input: not a number\n");
                }
            else
                {
                if (value < 0)
                {
                    printf("\nInvalid input: negative values not allowed\n");
                }
                else if (errno != 0 || value > INT_MAX)
                    {
                        printf("\nInvalid input: value too large for type int\n");
                    }
                    else
                        {
                            return (int)value;
                        }
                }
            }
    }
    
    void fact_fun(int num_fact)
    {
        int fact = 1;
        for (int i = 1; i <= num_fact; i++)
            {
            if (fact > INT_MAX / i)
            {
                printf("\nInvalid input: arithmetic overflow\n");
                return;
            }
            fact = fact * i;
        }
        printf("\nFactorial of %d is %d\n", num_fact, fact);
    }