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

3
我试图将字符串中的数字转换为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 能够实现你所需的功能吗?最好举个例子,提供输入和期望的输出。 - Nam Nguyen
int(chars_and_numers[i])并不像你想象中的那样工作。char类型是一种整型,就像intshort一样。它保存了字符的(通常是)ASCII整数值,这就是为什么'0'在你的数组中显示为48。要将数字转换为其整数等效项,请使用chars_and_numbers[i] - '0',它从数字的ASCII值中减去了'0'的整数值,得到'0'0'1'1,以此类推。当然,对于这种特殊情况,您可能希望使用stringstream,因此这并没有太大帮助,但至少可以教会您一些东西。 - Chris Lutz
我再一次希望有一个不存在的“transform_if”算法。 - Benjamin Lindley
你最终希望 only_numbers 看起来像 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 } 还是 { 123, 456, 789, 0 } - Chris Lutz
像第一个一样。stringstream 会给我字符之间的数字而不是单个数字吗? - Tiago
2个回答

4
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}。但我可能错了,这是不明确的。 - Chris Lutz
是的,这不是很清楚。我假设他提到的“digits”是指单个数字。 - Eric Z
是的,Eric和George Gaál,我只需要单个数字。这正是我要找的。谢谢。 - Tiago
@Tiago,如果Eric的答案解决了你的问题,你应该将其标记为已接受。 - Nam Nguyen

-1
如果您希望在打印整数向量时输出实际数字0到9,则可以依赖于ASCII值'0'到'9'是连续的这一事实。
only_numbers.push_back(char_and_numbers[i] - '0');

因此,'8'变成了'8' - '0',即56-48,这就是8。

2
你不需要依赖ASCII,你可以依赖标准规定数字字符在字符集中连续存储。 (它对字母字符没有做同样的事情,实际上EBCDIC也没有这样做,但对于数字,您是安全的。) - Chris Lutz
@George Gaál - 我希望你不会使用 std::string 来处理 Unicode。 - Chris Lutz
有很多误解。据我了解,Unicode 有不同的类型。其中之一是 UTF-8,在 std::string 中非常适用。但我不能说这是最好的容纳方式。 - George Gaál
1
George:不幸的是,还存在许多关于误解的误解。Unicode 只有一个。(但是有很多方法来表示 Unicode 代码点序列。) - Kerrek SB
@Kerrek SB,您是正确的。但代码点是指一些数字,我们可以进行分析。并且还可以进行减法 :) - George Gaál

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