如何解决拆分并从字符串转换为字符数组
如何转换:
string x = "1+2+3";
到:
char y[] = {'1','2','3'};
我应该采取什么方法?
解决方法
任务是分割一个由'+'分隔的字符串。在下面的示例中,使用了分隔符“,”。
将字符串拆分为标记是一项非常古老的任务。有许多可用的解决方案。都有不同的属性。有些难以理解,有些难以开发,有些更复杂、更慢或更快或更灵活。
替代方案
- 手工制作的许多变体,使用指针或迭代器,可能难以开发且容易出错。
- 使用旧式
std::strtok
函数。可能不安全。也许不应该再使用了 -
std::getline
。最常用的实现。但实际上是“误用”而不是那么灵活 - 使用专门为此目的开发的专用现代功能,最灵活且最适合 STL 环境和算法环境。但速度较慢。
请在一段代码中查看 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,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,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,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(),{});
print(c2);
// And works with algorithms
std::deque<std::string> c3{};
std::copy(std::sregex_token_iterator(stringToSplit.begin(),{},std::back_inserter(c3));
print(c3);
}
return 0;
}
,
您可以使用 std::vector<std::string>
代替 char[]
,这样,它可以处理多于一位的数字。试试这个:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
int main() {
using namespace std;
std::string str("1+2+3");
std::string buff;
std::stringstream ss(str);
std::vector<std::string> result;
while(getline(ss,buff,'+')){
result.push_back(buff);
}
for(std::string num : result){
std::cout << num << std::endl;
}
}
这里有一个 coliru link 表示它适用于一位以上的数字。
,这是我的步骤:
- 将原来的
string
转换成char*
- 使用函数
char*
将获得的+
与分隔符strtok
分割。我将每个令牌存储到vector<char>
- 将此
vector<char>
转换为 C 字符数组char*
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
int main()
{
string line = "1+2+3";
std::vector<char> vectChar;
// convert the original string into a char array to allow splitting
char* input= (char*) malloc(sizeof(char)*line.size());
strcpy(input,line.data());
// splitting the string
char *token = strtok(input,"+");
int len=0;
while(token) {
std::cout << *token;
vectChar.push_back(*token);
token = strtok(NULL,"+");
}
// end of splitting step
std::cout << std::endl;
//test display the content of the vect<char>={'1','2',...}
for (int i=0; i< vectChar.size(); i++)
{
std::cout << vectChar[i];
}
// Now that the vector contains the needed list of char
// we need to convert it to char array (char*)
// first malloc
char* buffer = (char*) malloc(vectChar.size()*sizeof(char));
// then convert the vector into char*
std::copy(vectChar.begin(),vectChar.end(),buffer);
std::cout << std::endl;
//now buffer={'1',...}
// les ut stest by displaying
while ( *buffer != '\0')
{
printf("%c",*buffer);
buffer++;
}
}
,
您可以在 https://repl.it/@JomaCorpFX/StringSplit#main.cpp
中运行/检查此代码代码
#include <iostream>
#include <vector>
std::vector<std::string> Split(const std::string &data,const std::string &toFind)
{
std::vector<std::string> v;
if (data.empty() || toFind.empty())
{
v.push_back(data);
return v;
}
size_t ini = 0;
size_t pos;
while ((pos = data.find(toFind,ini)) != std::string::npos)
{
std::string s = data.substr(ini,pos - ini);
if (!s.empty())
{
v.push_back(s);
}
ini = pos + toFind.length();
}
if (ini < data.length())
{
v.push_back(data.substr(ini));
}
return v;
}
int main()
{
std::string x = "1+2+3";
for (auto value : Split(x,u8"+"))
{
std::cout << "Value: " << value << std::endl;
}
std::cout << u8"Press enter to continue... ";
std::cin.get();
return EXIT_SUCCESS;
}
输出
Value: 1
Value: 2
Value: 3
Press enter to continue...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。