在 std::string 中仅将数字转换为 int

Posted

技术标签:

【中文标题】在 std::string 中仅将数字转换为 int【英文标题】:Convert only digits to int in a std::string 【发布时间】:2011-08-11 01:26:21 【问题描述】:

我正在尝试仅将数字从字符串转换为 int 向量,但这给了我数字 0 到 9 的 ASCII 码。

有没有办法只将数字转换为整数?我想我必须使用 char 数组,因为 atoi() 不适用于 std::string 并且 c_str() 方法不适用于每个字符,仅适用于整个字符串。

#include <cctype>
#include <iostream>
#include <vector>

using namespace std;

int main() 
    string chars_and_numbers = "123a456b789c0";
    vector<int> only_numbers;

    for (int i = 0; i < chars_and_numbers.length(); i++) 
        if (isdigit(chars_and_numbers[i])) 
            cout << chars_and_numbers[i] << " ";
            only_numbers.push_back(int(chars_and_numbers[i]));
        
    

    cout << endl;

    for (vector<int>::iterator i = only_numbers.begin(); i != only_numbers.end(); i++) 
        cout << *i << " ";
    

    return 0;

输出:

1 2 3 4 5 6 7 8 9 0
49 50 51 52 53 54 55 56 57 48

【问题讨论】:

istringstream 会满足您的需求吗?更好的是,请给出示例输入和预期输出。 int(chars_and_numers[i]) 没有做你认为应该做的事情。 char 类型是一个整数类型,如 intshort。它保存字符的(通常)ASCII 整数值,这就是'0' 在您的数组中显示为48 的原因。要将数字转换为其等效整数,请使用chars_and_numbers[i] - '0',它从数字的ASCII 值中减去'0' 的整数值,得到0 对应'0'1 对应'1',依此类推。当然,对于这种特殊情况,您可能希望使用stringstream,所以这不是很有帮助,但它至少应该教会您一些东西。 我再次希望不存在的transform_if 算法。 无论如何,你想让only_numbers 在你完成后看起来像 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 还是 123, 456, 789, 0 喜欢第一个。 stringstream 会给我字符之间的数字而不是单个数字? 【参考方案1】:
ASCII Character    ASCII Code(decimal)  Literal Integer
      '0'               48                      0
      ...               ...                    ...
      '9'               57                      9

int(chars_and_numbers[i]) 为您返回 ASCII 字符的底层 ASCII 代码,而不是您想要的文字整数。

一般来说,如果i 属于 [0, 9],'i' - '0' 的结果是 i

例如'1' - '0' 返回两个 ASCII 字符 (49 - 48) 的值之间的 距离,即 1

int main() 
    string chars_and_numbers = "123a456b789c0";
    vector<int> only_numbers;

    for (int i = 0; i < chars_and_numbers.length(); i++) 
        if (isdigit(chars_and_numbers[i])) 
            cout << chars_and_numbers[i] << " ";
            // here is what you want
            only_numbers.push_back(chars_and_numbers[i] - '0');
        
    

    cout << endl;

    for (vector<int>::iterator i = only_numbers.begin(); i != only_numbers.end(); i++) 
        cout << *i << " ";
    

    return 0;

【讨论】:

我认为 OP 实际上 想要做的是让only_numbers 持有 123, 456, 789, 0 。但我可能是错的。这是模棱两可的。 是的,还不是很清楚。我假设他提到的“数字”是单个数字。 是的,Eric 和 George Gaál,我只想要单个数字。这正是我一直在寻找的。谢谢。 @Tiago,如果 Eric 的回答解决了您的问题,您应该将其投票为接受。【参考方案2】:

如果您在打印整数向量时所需的输出是实际的数字 0 到 9,那么您可以相信 '0' 到 '9' 的 ASCII 值是连续的:

only_numbers.push_back(char_and_numbers[i] - '0');

因此,'8' 变为 '8' - '0',或 56 - 48,即 8。

【讨论】:

您不需要依赖 ASCII,您可以依赖标准要求数字字符在字符集中连续存储的事实。 (它不会对字母字符做同样的事情,EBCDIC 确实不会这样做,但对于数字你是安全的。) @George Gaál - 你不会将std::string 用于Unicode(我希望)。 有很多误解。据我了解,有不同类型的 Unicode。其中之一是 UTF-8,它非常适合 std::string。但我不能说这是遏制它的最佳方式。 George:不幸的是,围绕这些误解也存在许多误解。只有一个 Unicode。 (但是有很多方法可以表示一系列 Unicode 代码点。) @Kerrek SB,你是对的。但是代码点指的是一些我们可以分析的数字。也减去:)

以上是关于在 std::string 中仅将数字转换为 int的主要内容,如果未能解决你的问题,请参考以下文章

在c ++ 11中将std :: string转换为char * [重复]

C++中如何将int或者char转化为string类

在 ListView 中仅将标题设为粗体

在 std::unordered_set<const char *> 中找不到转换为 const char * 的 std::string

在 C# 中仅将类型作为参数传递

如何在 Latex 中仅将一位作者与其他三位作者居中对齐