首页 > 解决方案 > 如何在 C++ 中将字符串转换为数组?

问题描述

我正在尝试将字符串转换为 C++ 中的数组。我的字符串是: [1, 2, 3] 我需要取出数字并将它们放入一个数组中。到目前为止我尝试过的是:

char A[] ={};
short loop = 0;
string line1 = [1, 2, 3];
for(int i = 0 ; i < line1.length(); i++){
  if(line1[i] == '[' || line1[i] == ',' || line1[i] == ' '|| line1[i] == ']')
  continue;
else{

{  A[loop] = line1[i];
loop++;
}}}

出于某种原因,我没有得到正确的价值观。

标签: c++

解决方案


你想要什么还不是很清楚。

示例:如果您的 astd::string始终只包含 3 个数字,那么您可以将字符串放入 a 中std::istringstream,然后使用提取运算符>>提取您想要的内容。

简单的例子:

#include <iostream>
#include <string>
#include <sstream>

int main() {
    // Our test string
    std::string line{"[1, 2, 3]"};

    // Here we will store the 3 numbers
    int number1{}, number2{}, number3{};

    // The brackets and the comma will be stored in a dummy variable
    char dummy;

    // Now, put the string into an istringstream, so that we can extract data from it.
    std::istringstream iss{ line };

    // And, extract the values:
    iss >> dummy >> number1 >> dummy >> number2 >> dummy >> number3 >> dummy;

    //Show result:
    std::cout << number1 << '\t' << number2 << '\t' << number3 << '\n';
}

野生的假人不被使用和丢弃。您当然也可以从字符串中提取值并将它们直接放入固定大小的数组中

#include <iostream>
#include <string>
#include <sstream>

int main() {
    // Our test string
    std::string line{"[1, 2, 3]"};

    // Here we will store the 3 numbers
    int intArray[3];

    // The brackets and the comma will be stored in a dummy variable
    char dummy;

    // Now, put the string into an istringstream, so that we can extract data from it.
    std::istringstream iss{ line };

    // And, extract the values:
    iss >> dummy >> intArray[0] >> dummy >> intArray[1] >> dummy >> intArray[2] >> dummy;

    //Show result:
    std::cout << intArray[0] << '\t' << intArray[1] << '\t' << intArray[2] << '\n';
}

如果字符串中的数字数量是可变的,那就有点困难了。因此,例如超过 3 个。

然后你需要一种变长数组。这存在于 C++ 中并称为std::vector. 它可以动态增长并在许多许多 C++ 应用程序中使用。

好的,现在我们知道在哪里存储了。但是,如何继续。首先,有很多潜在的解决方案。但一个简单的方法是用空格替换括号。结果将是一个逗号分隔的值列表。这需要拆分为其组件。

对于拆分 CSV(逗号分隔值)字符串,还有许多潜在的解决方案。我会在这篇文章的最后展示一些。

但是现在,我将简单地将所有无数字替换为空格并使用循环来提取所有值。提取的值将被psuhed到std::vector

#include <iostream>
#include <string>
#include <sstream>
#include <cctype>
#include <vector>

int main() {
    // Our test string
    std::string line{"[1, 2, 3, 4]"};

    // Here we will store the numbers
    std::vector<int> numbers{};

    // Replace all none digits with space
    for (char& c : line) if (not std::isdigit(c)) c = ' ';

    // Now, put the string into an istringstream, so that we can extract data from it.
    std::istringstream iss{ line };

    // And, extract the values:
    int value;
    while (iss >> value) numbers.push_back(value);

    //Show result:
    for (int& n : numbers) std::cout << n << '\t';
}

如前所述,拆分 CSV 字符串有更多可能的解决方案。请参阅 4 个附加解决方案:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <regex>
#include <algorithm>
#include <iterator>
#include <cstring>
#include <forward_list>
#include <deque>

using Container = std::vector<std::string>;
std::regex delimiter{ "," };


int main() {

    // Some function to print the contents of an STL container
    auto print = [](const auto& container) -> void { std::copy(container.begin(), container.end(),
        std::ostream_iterator<std::decay<decltype(*container.begin())>::type>(std::cout, " ")); std::cout << '\n'; };

    // Example 1:   Handcrafted -------------------------------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Search for comma, then take the part and add to the result
        for (size_t i{ 0U }, startpos{ 0U }; i <= stringToSplit.size(); ++i) {

            // So, if there is a comma or the end of the string
            if ((stringToSplit[i] == ',') || (i == (stringToSplit.size()))) {

                // Copy substring
                c.push_back(stringToSplit.substr(startpos, i - startpos));
                startpos = i + 1;
            }
        }
        print(c);
    }

    // Example 2:   Using very old strtok function ----------------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Split string into parts in a simple for loop
#pragma warning(suppress : 4996)
        for (char* token = std::strtok(const_cast<char*>(stringToSplit.data()), ","); token != nullptr; token = std::strtok(nullptr, ",")) {
            c.push_back(token);
        }

        print(c);
    }

    // Example 3:   Very often used std::getline with additional istringstream ------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Put string in an std::istringstream
        std::istringstream iss{ stringToSplit };

        // Extract string parts in simple for loop
        for (std::string part{}; std::getline(iss, part, ','); c.push_back(part))
            ;

        print(c);
    }

    // Example 4:   Most flexible iterator solution  ------------------------------------------------

    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };


        Container c(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
        //
        // Everything done already with range constructor. No additional code needed.
        //

        print(c);


        // Works also with other containers in the same way
        std::forward_list<std::string> c2(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});

        print(c2);

        // And works with algorithms
        std::deque<std::string> c3{};
        std::copy(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {}, std::back_inserter(c3));

        print(c3);
    }
    return 0;
}

推荐阅读