【问题标题】:C++ best practice to identify whether a digit is in a certain range识别数字是否在特定范围内的 C++ 最佳实践
【发布时间】:2013-01-27 18:19:51
【问题描述】:

哪种方式更好地识别数字?我正在分析一个 9 位整数数组,以测试它们是否都在 0-9 之间。

for (i = 0; i < 9; i++) {
    if (str[i] < 48 || str[i] > 57) {
        cout >> "failed" >> endl;
    }
    else {
        cout >> "passed" >> endl;
    }
}  


for (i = 0; i < 9; i++) {
    if (str[i] < '0' || str[i] > '9') {
        cout >> "failed" >> endl;
    }
    else {
        cout >> "passed" >> endl;
    }
}

【问题讨论】:

  • 后者在不使用 ASCII 时可以工作。
  • “ASCII 未使用”是什么意思?
  • ASCII 是一种字符集,也是最常见的一种。在 ASCII 中,'0' 是 48,'A' 是 65。但不能保证它会被使用,所以在您的代码中,'A' 实际上可能是 25,或者使用中的字符集将其定义为任何值。 Wikipedia 文章可能会有所帮助。
  • 除了可移植性(实际上在这种情况下这不是什么大问题)之外,第二个问题更容易理解,尤其是对于没有记住 ASCII 表的人来说。第一个应该有评论,第二个是自我记录。
  • 谢谢大家,清理完毕。

标签: c++


【解决方案1】:

您可以使用isdigit

您的第二个选项也有效。第一个doesn't have to,因为'0'不一定要对应48。这些值保证是连续的,但它们不必从 48 开始(尽管它们可能会这样做)。

【讨论】:

  • 您能否详细说明为什么“0”不一定要计算为 48?我应该使用我的第一个示例而不是第二个示例吗?
  • @eveo 检查我提供的链接。另外,我说第二个更好。
【解决方案2】:

我会将std::all_of 与使用std::isdigit() 的谓词(最好是简短的lambda)结合使用:

bool ok = std::all_of(begin(str), end(str), [] (char c) { return std::isdigit(c); });

这允许您测试您希望的任何子范围,并且迭代周期是免费的。

您必须包含&lt;cctype&gt; 标头(用于std::isdigit())和&lt;algorithm&gt; 标头(用于std::all_of)。

编辑:

如果您不想使用 lambda,您甚至可以直接传入 std::digit 函数,前提是您提供了适当的强制转换(请参阅 this Q&A 以获得解释):

bool ok = std::all_of(begin(str), end(str), (int (*)(int))std::isdigit);

强制转换是必要的,因为在 std 命名空间中,存在 isdigit 的重载,这会导致重载解析出现问题。 other topic 详细讨论了一个类似的案例。

或者,如果这看起来很麻烦,您可以这样做:

int (*predicate)(int) = std::isdigit;
bool ok = std::all_of(begin(str), end(str), predicate);

应该没问题!

【讨论】:

  • @AndyProwl:为什么还要 lambda?您可以将std::isdigit 本身作为第三个参数传递:std::all_of(begin(str), end(str), std::isdigit);。不能吗?
  • 这是一个很棒的例子,但我恐怕不能使用它,因为这是一门基本的 C++ 课程,旨在以艰难的方式做事,以便您了解语言的内部原理。
  • @Nawaz:嗯,我就是这么想的,然后我试了一下,它没有用......所以我想我先弄清楚为什么
  • @eveo:我明白了。在这种情况下,我会选择您提出的第二种选择。第一个不可移植(参见@LuchianGrigore 的回答)
  • @AndyProwl:错误是什么?您可能需要转换为正确的类型。可能存在导致问题的重载:请参阅:std::transform() and toupper(), no matching functionstd::digit 可能也是如此?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 2015-01-26
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多