c++ - 如何在 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++;
}}}
出于某种原因,我没有得到正确的价值观。
解决方案
你想要什么还不是很清楚。
示例:如果您的 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;
}
推荐阅读
- php - PHP 中的短 IF 和长 IF 变量赋值方法
- c++ - 使用类成员创建数组
- c# - C# SocketIOClientDotNet 似乎不起作用
- python - 如何在 SymPy 中定义一个通过 .equals() 比较元素的 FiniteSet
- json - 如何通过 JSON 文件中的链接从本地文件夹加载图像?
- yarnpkg - yarn 如何找到作为开发依赖项安装的模块
- java - 无法从 'optional:configserver:http://localhost:8090 - SpringBoot 2.4.0 Illford 2020.0.0-M3 加载配置数据
- c++ - 在没有结构实例的情况下获取非静态结构字段的地址会产生什么?
- c++ - 我如何包含空格以从文件输入到结构数组
- python - 我无法绘制填充矩形