【问题标题】:C++ See If Argument Is NumericC++ 查看参数是否为数字
【发布时间】:2016-09-14 08:09:11
【问题描述】:

我正在用 C++ 创建一个加密/解密程序,并使用三个用户提供的数字来自定义加密。我在 cplusplus.com 上阅读了有关 isdigit() 的信息,并基于此制作了一个函数:

bool is_numeric(char *string)
{
    int sizeOfString = sizeof(string);
    int iteration = 0;
    bool isNumeric = true;

    while(iteration < sizeOfString)
    {
        if(!isdigit(string[iteration]))
        {
            isNumeric = false;
            break;
        }

        iteration++;

    }

    return isNumeric;
}

但是,它似乎不起作用。无论我给它一个数字还是一个非数字字符,它仍然返回 false。我的方法有什么问题。

【问题讨论】:

  • 把你的字符串叫做string有点危险。如果你使用标准,那么你可能会遇到一些问题,特别是如果你使用命名空间标准。
  • 我不使用use namespace std。我总是使用std::whatever,这似乎是正确的做事方式。
  • sizeof 返回调用它的类型的编译时大小。字符串变量的类型为char *,因此您将获得char * 变量的大小。请注意,对于 C 数组,数组的类型也是它的大小。例如。 int foo[100] 的类型是 100 个整数的数组。请注意,在许多情况下,这些数组会默默地衰减为指针。 ideone.com/gYqUiY 可能有用。
  • 您也可以使用strspn 并检查其返回值是否为strlen(string)。这会将您的函数折叠成一行,此外,您可以在需要时添加其他字符。

标签: c++ command-line-arguments numeric


【解决方案1】:

我想我会使用标准算法:

bool is_numeric(char const *string)
{
    return std::all_of(string, string+strlen(string), 
                       [](unsigned char c) { return ::isdigit(c); });
}

请注意,就目前而言,您的代码可能(通常会)具有未定义的行为(如果字符串包含任何在编码为 char 时结果为负数的内容)。这段代码通过将 char 转换为 unsigned char 来防止这种情况,因为它被传递给 lambda ——这就是为什么我使用 lambda 而不是仅仅将 ::isdigit 作为谓词传递给 all_of

【讨论】:

    【解决方案2】:

    您正在计算 sizeOfString 错误。试试这个吧。

    bool is_numeric(char *string)
    {
        int sizeOfString = strlen(string);
        int iteration = 0;
        bool isNumeric = true;
    
        while(iteration < sizeOfString)
        {
            if(!isdigit(string[iteration]))
            {
                isNumeric = false;
                break;
            }
    
            iteration++;
    
        }
    
        return isNumeric;
    }
    

    您可能还想添加检查. 字符的功能!现在你的代码只有在你的字符串是一个整数时才返回 true。

    【讨论】:

    • 这当然解决了它。感谢您纠正我的愚蠢错误。
    • 还可以考虑使用for-loop 以使您的代码更具可读性。此外,i 经常用于简单的迭代变量:for(int i=0; i&lt;sizeOfString; i++){/*your code*/}
    • @JerryCoffin 这是因为À 的值是192,使其成为扩展ASCII 代码 的一部分。这超出了char [max: 127] 的限制。
    • @KirkBackus:这是一个合理的(并且在世界的某些地方很常见)的角色。不,它不是由 ASCII 定义的,但几十年来没有人使用过 ASCII。
    • @JerryCoffin ASCII 是一个非常古老的标准,但任何使用char 的人都仅限于ASCII 字符。由于UTF-8ASCII 完全向后兼容,因此技术上每个人都在使用ASCII(当第一位为0 时)。
    【解决方案3】:
    while ('0' <= *string && *string <= '9')
        ++string;
    return *string == '\0';
    

    或者,如果您更喜欢使用isdigit

    while (is digit((int)*string))
        ++string;
    return *string == '\0';
    

    【讨论】:

    • 你真的想投到unsigned char,而不是int。从charint 的提升是自动发生的,但否定输入将保持否定状态,因此您仍然会得到未定义的行为。
    • @JerryCoffin - 是的,太仓促了。
    【解决方案4】:

    另一种可能的解决方案是使用字符串流:

    bool isNumeric(const string& s) {
        stringstream ss(s);
        int val;
        ss >> val;
        return ! ss.fail() && ss.eof();
    }
    

    stringstream::operator>>(int&) 如果给定字符串不是数字,则设置字符串流的故障位,并且您需要检查字符串中的所有内容是否都是一个整数(仅此而已),所以您还测试了 eof 位。 这也适用于负数,如果您想接受浮点数,也可以将 int 更改为 double。

    【讨论】:

      猜你喜欢
      • 2016-02-09
      • 2016-10-10
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 2015-05-28
      • 1970-01-01
      • 2014-04-03
      • 2017-07-14
      相关资源
      最近更新 更多