isdigit函数无法正常工作

3
我正在尝试通过遍历整个字符串并输出整数来测试字符串是否包含整数。我的方法涉及将字符串转换为c-string,使用atoi函数将c-string转换为整数,然后使用isdigit函数测试它是否为整数。出于某种未知的原因,isdigit函数返回false,即使它遇到了一个整数。
我需要帮助解决这个问题。
#include <iostream>
using namespace std;
#include <string>

int main()
{
    string p = "[ab, e2cd]";

    for (int k = 0; k < p.length(); k++)
    {
        if (isdigit(atoi(p.substr(k,1).c_str())) == true) //testing done here
        {
            cout << atoi(p.substr(k, 1).c_str());
        }
    }
}

1
传递一个字符即可。 - Sully
使用 if (isdigit(*(p.substr(k,1).c_str())) == true) //testing done here 进行快速而不太规范的更改。 - abasu
3个回答

3

isdigit 接受一个整数参数,其值应为本地语言环境下的单个字符。将 char 类型强制转换为 unsigned char 类型再传递给它,然后转换为 int 类型是可以的。由于 string 包含 char 型元素,您可以像这样使用它的元素:

if ( static_cast<unsigned char>(isdigit(p[k])) ) { ....

2

atoi函数将一个C字符串转换为数字。如果字符串无效,你不会知道,因为atoi返回0,这也可能是字符串中的数字。

isdigit应该传递一个字符作为整数,并在不是数字字符时返回false。所以你是在比较苹果和橘子。

只需遍历字符串并将每个字符传递给isdigit(),如果成功,则可以使用atoi进行转换。

然而,有一个陷阱,即字符串包含+-作为数字的一部分,而isdigit()在这种情况下不返回true。还可能有其他字符作为有效数字的一部分,但对于简单的整数值,这应该足够了。


2
isdigit的行为相当奇怪,这是由于历史原因造成的。
它接收一个字符值,并告诉你它是否是十进制数字('0''1',... '9' 中的一个)-- 这意味着将其应用于 atoi() 的结果很少有意义。
但是,该字符值不是表示为 char,而是作为其值在 unsigned char 范围内的 int 表示。除了 EOF(通常为 -1)以外,任何其他参数值都会导致未定义的行为。因此,如果要测试一个 char 值,应将其转换为 unsigned char;如果普通的 char 是带符号的,则省略转换会存在未定义行为的风险。
而且结果不是 bool。它是一个值为 0 的 int,表示非数字,对于数字则是任意的非零值。不要将结果与 true 进行比较。事实上,不要将任何表示条件的值与 falsetrue 进行相等或不等的比较;它已经是条件了,所以直接使用它即可。
如果 c 是一个 char,替换为:
if (isdigit(c) == true)

by

if (isdigit((unsigned char)c))

或者

if (isdigit(static_cast<unsigned char>(c)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接