[英]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_view
和std::from_chars()
來減少 memory 開銷,因此您不必為sub
或std::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.