将字符串解析为C ++中的数字数组?

Raf*_*Dev 0 c++ string

我最近开始使用C ++,在适应其他语言时遇到了一些困难。我敢肯定有一个更简单的解决方案,但是我不知道为什么这行不通。

基本上,我需要一种将输入(例如5 66 193(整数的未知长度))转换为向量/其他内容(例如“ [5, 66, 193]”)的方法。

这是我的代码:

vector<int> A;
string AToParse;
getline(cin, AToParse);
int pos = 0;
while (pos < AToParse.length()) {
    if (AToParse[pos] == ' ') {
        pos++;
        continue;
    }
    string tmp = "" + AToParse[pos];
    if (pos + 1 >= AToParse.length()) break;
    for (int i = pos + 1; i < AToParse.length(); i++) {
        if (AToParse[i] == ' ') {
            pos = i + 1;
            break;
        } else {
            tmp += AToParse[i];
        }
    }
    int tmpint = stoi(tmp);
    A.push_back(tmpint);
}
for (int Ai : A) {
    cout << Ai << endl;
}
Run Code Online (Sandbox Code Playgroud)

wal*_*nut 6

要求#includeS代表<sstream><iterator>

std::stringstream parseStream{AToParse};
std::vector<int> A(std::istream_iterator<int>{parseStream}, std::istream_iterator<int>{});
Run Code Online (Sandbox Code Playgroud)

std::stringstream的行为与std::cin或相同std::ifstream,只是它使用std::string传递给它的缓冲区作为输入缓冲区。因此,您也可以使用int x; parseStream >> x;等。

std::istream_iterator<int>是一个方便的迭代器,它可以int从流中读取s并丢弃空白。(与parseStream >> x;重复的行为相同)

std::vector带有两个参数的构造函数将第一个参数视为对源范围的开头进行迭代的迭代器,以从该范围构造向量,第二个参数将该范围的末尾构造。

默认构造std::istream_iterator<int>表示流输入操作的结束或失败。

将所有这些放在一起,将通过从中读取整数并AToParse丢弃空白来构造向量,直到到达字符串的末尾或发生输入失败(例如,因为字符串包含不可解释为整数的字符)。


为了使代码更简洁,您可以省略第二个迭代器的类型。迭代器将从空括号括起来的初始值设定项列表中以正确的类型构造,因为由于std::vector构造函数要求将其推导为与第一个参数的类型相同,所以:

std::stringstream parseStream{AToParse};
std::vector<int> A(std::istream_iterator<int>{parseStream}, {});
Run Code Online (Sandbox Code Playgroud)

从C ++ 17开始,您可以删除类型名称的多余重复std::vector。由于C ++ 17中的这一新功能(称为类模板参数推导(CTAD)),将可以从迭代器中正确推断出它,并且您必须提及只希望一次从字符串读取的类型,这与Dont一致。重复自己的规则:

std::stringstream parseStream{AToParse};
std::vector A(std::istream_iterator<int>{parseStream}, {});
Run Code Online (Sandbox Code Playgroud)

但是请注意,仅当对std::vector初始化程序使用括号时,这才可以完成预期的操作。用大括号括起来的初始化程序列表将无法正确执行操作。