簡體   English   中英

將字符串解析為 C++ 的數組

[英]Parsing a string into an array for C++

如何將字符串解析為 C++ 中的數組?

例如: "[1:2:3:4]cd/dvd PLDS DVD-RW DU8A6SH DU53 /dev/sr0"

我想在方括號[]中獲取一個整數數組。 所以數組包含{1, 2, 3, 4}

下面是我寫的代碼,但我不確定這是否是最有效的方法。

std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";
int begin = test.find("[");
begin = begin + 1;
std::string sub = test.substr(begin,7);
std::replace(sub.begin(), sub.end(), ':', ' ');

std::vector<int> arr;
std::stringstream ss(sub);
int temp;
while (ss >> temp)
     arr.push_back(temp);

注意: "["之前不會出現某些內容。 "["將始終存在。 這些數字將始終是一個數字。 方括號內總是有四個整數。 "]"將始終存在。 文本總是跟在"]"之后。

鑒於您添加的約束,您可以嘗試以下操作:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>

int main() {
    std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";

    std::vector<int> v(4);
    {
        char open_square_bracket, colon1, colon2, colon3, close_square_bracket;
        std::stringstream ss(test);
        ss >> open_square_bracket >> v[0] >> colon1 >> v[1] >> colon2 >> v[2] >> colon3 >> v[3] >> close_square_bracket;
    }

    copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, ", "));
    std::cout << "\n";

    return 0;
}

當然,重要的部分是我放在塊語句中的部分,以突出顯示它。 這使您還可以檢查字符是否是它們應該是的。 否則,如果您 100% 確定格式正確,則可以簡化為

    std::vector<int> v(4);
    char c;
    std::stringstream ss(test);
    ss >> c >> v[0] >> c >> v[1] >> c >> v[2] >> c >> v[3] >> c;

你也可以將它包裝在一個 for 循環中,但如果它總是 4 個元素,為什么還要麻煩呢?

當然,在這種情況下可以使用std::array<>

    std::array<int, 4> v;
    char c;
    std::stringstream ss(test);
    ss >> c >> v[0] >> c >> v[1] >> c >> v[2] >> c >> v[3] >> c;

ideone上運行它。

由於您正在硬編碼substr()的大小,這意味着數字具有固定的位置和寬度,在這種情況下,您可以簡單地使用它來代替:

#include <string>
#include <array>

std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";

std::array<int, 4> arr; // or: int arr[4]; pre-C++11
for(int i = 1, j = 0; i < 9; i += 2, ++j)
    arr[j] = test[i]-'0';

現場演示

但是,如果不是這種情況,則不要假設關閉]的位置。 使用find()來定位它,例如:

std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";

std::string::size_type begin = test.find('[') + 1;
std::string::size_type end = test.find(']', begin);
std::string sub = test.substr(begin, end - begin);

std::vector<int> arr;
std::istringstream iss(sub);
int temp;

while (iss >> temp) {
    arr.push_back(temp);
    iss.ignore();
}

現場演示

如果您使用 C++17 或更高版本,您可以使用std::string_viewstd::from_chars()來減少 memory 開銷,因此您不必為substd::istringstream分配單獨的std::string ,甚至根本使用std::istringstream ,例如:

std::string test = "[1:2:3:4]cd/dvd  PLDS  DVD-RW DU8A6SH DU53  /dev/sr0";
std::string_view sv(test.data(), test.size());

std::string_view::size_type begin = sv.find('[') + 1;
std::string_view::size_type end = sv.find(']', begin);
std::string_view sub = sv.substr(begin, end - begin);

std::vector<int> arr;
const char *pBegin = sub.data(), *pEnd = pBegin + sub.size();
int temp;

while (pBegin < pEnd)
{
    auto [ptr, ec] = std::from_chars(pBegin, pEnd, temp);
    if (ec != std::errc()) break;
    arr.push_back(temp);
    pBegin = ptr + 1;
}

現場演示

int main()
{
    std::string str = "[1:2:3:4]aaa";
    std::vector<int> str_chars = {};

    for (unsigned int i = 0; i < str.size(); ++i)
    {
        char curr = str.at(i);
        if (str.at(i) == '[')
        {
            str_chars.push_back((str.at(i + 1) - '0'));
        }
        else if ((str.at(i) == ':'))
        {
            str_chars.push_back(str.at(i + 1) - '0');
        }
    }

    for (int i = 0; i < str_chars.size(); ++i)
    {
        printf("%d ", str_chars.at(i));
    }

    getchar();
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM