【问题标题】:Why is my isdigit() function returning the ascii code instead of the int, and how do I prevent it? [duplicate]为什么我的 isdigit() 函数返回的是 ascii 代码而不是 int,我该如何防止它? [复制]
【发布时间】:2019-02-08 23:51:47
【问题描述】:

下面的代码 sn-p 应该遍历一个字符串(单词)向量,如果字符串包含一个整数,它应该将 int 推入一个仅包含这些数字的整数向量(nums)。

for (int i = 0; i < words.size(); i++){
    for(int j = 0; j < words.at(i).size(); j++){
        if (isdigit(words[i][j])){
            nums.push_back(words[i][j]);
        }
    }
    cout << words.at(i) << endl;
}

我收到了一个文件,上面有文字。我的代码成功地从文件中提取单词并将它们放在向量中。但是,我的 isdigit() 函数没有返回预期值。话是ho1d h4m, 舞蹈2, 8st, 下一个, 最重要的, se3d, tes7,我对 nums 向量的期望值为 1、4、2、8、6、3、7。这是我的打印 sn-p:

for (int i = 0; i < nums.size(); i++){
        cout << nums.at(i) << " ";
    }

但它返回的值是 49 52 50 56 54 51 55。编辑:刚刚认识到这些是 ascii 值。如何防止他们推送 ascii 值而不是整数?我什至尝试使用 get() 函数并在读取输入时遍历每个字符而不是每一行,我仍然得到相同的返回值。我哪里错了?

【问题讨论】:

  • 看看这些数字。您是否看到了如何将这些数字转换为整数的模式(即使 ASCII 值是整数)?有没有想到数字48 或字符'0'
  • 数值0到9与字符'0''9'有区别。
  • 如果找到两位或更多位的代码应该怎么做?它们是分开处理还是作为一个更大的整数处理?

标签: c++


【解决方案1】:

你可以像下面这样使用 atoi():

  for (int i = 0; i < words.size(); i++)
  {
    for(int j = 0; j < words.at(i).size(); j++)
    {
        if (isdigit(words[i][j]))
        {
            char c = words[i][j];
            nums.push_back(atoi(&c));
        }
    }
    std::cout << words.at(i) << std::endl;
  }

对于 C++,您可以使用 stoi stl 函数

【讨论】:

  • 注意atoi 在这里使用将尝试读取多个连续数字。例如,如果输入包含b10ck,这将得到数字10,然后是数字0(原始代码将得到数字1,然后是数字0)。
  • atoi 在这里完全没有必要。对于单个数字,只需减去 '0'
  • @aschepler:修改代码以涵盖您提到的场景
  • 这种更改不好,因为现在&amp;c 不是以空值结尾的字符串。真的,只需使用words[i][j] - '0'。 C++ 确实保证isdigit 将只为十个普通数字字符返回真值,而不管语言环境如何,并且这十个数字字符具有连续的数值,即使这些值与 ASCII 不一致。
【解决方案2】:

当您将words[i][j] 添加到nums 向量时,您可以这样做:

nums.push_back(words[i][j] - '0');

说明:由于 ASCII 表中的第一个数字是 '0',因此您可以从其他数字(如 char 值)中减去它,以获得数字的差。

这是一个完整的例子:

#include <vector>
#include <string>
#include <iostream>

int main() {
    std::vector<std::string> words = { "ho1d", "h4m", "dance2", "8est", "next", "di6est", "se3d", "tes7"};
    std::vector<int> nums;

    for (int i = 0; i < words.size(); i++){
        for(int j = 0; j < words.at(i).size(); j++){
            if (isdigit(words[i][j])){
                nums.push_back(words[i][j] - '0');
            }
        }
        std::cout << words.at(i) << std::endl;
    }

    for (int i = 0; i < nums.size(); i++){
        std::cout << nums.at(i) << " ";
    }
}

此代码打印:

ho1d
h4m
dance2
8est
next
di6est
se3d
tes7
1 4 2 8 6 3 7 

【讨论】:

  • 非常感谢。你能解释一下为什么会这样吗?
  • 我已经编辑了帖子并添加了解释。基本上,0 字符的代码为48,其他数字为'1'=49'2'=50'3'=51 等。所以如果你减去,假设是'4'(代码=52'0',结果是你想要的4(因为52 - 48 = 4)。
  • 不仅仅是 ASCII。无论字符编码如何,语言定义都需要它。 '0''9' 的值必须是连续的且递增的,因此当 ch 包含任何字符 '0'..'9' 时,ch - '0' 始终有效。
猜你喜欢
  • 2022-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 2021-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多