我想将数据存储在对象数组中,但是我不知道如何分割字符串。
我希望看到的结果是:
tab[0].username = "user1"
tab[0].ip = "192.168.0.1"
tab[1].username = "user2"
tab[1].ip = "192.168.0.2"
tab[2].username = "user3"
tab[2].ip = "192.168.0.3"
这是我的字符串的外观:
user1:192.168.0.1|user2:192.168.0.2|user3:192.168.0.3
我当前拥有的代码,仅允许您拆分而不管理管道:
void addInTab(std::vector<std::string> vec, client *tab, int total_user)
{
for(int i = 0; i < 2; ++i) {
if (i == 0)
tab[total_user].username = vec[i];
if (i == 1)
tab[total_user].ip = vec[i];
}
}
void split(std::string str, char delim)
{
std::vector<std::string> vec;
std::string::size_type tmp = str.find(delim);
while(tmp != std::string::npos) {
vec.push_back(str.substr(0, tmp));
str = str.substr(tmp + 1);
tmp = str.find(delim);
}
vec.push_back(str);
addInTab(vec);
}
感谢前进
答案 0 :(得分:1)
我建议您创建split
函数的更通用的版本,该函数返回向量而不是调用某些特殊函数。
然后您可以先调用它以分割竖线字符,然后在循环中再次调用它 分割每个子字符串。
类似这样的东西
std::vector<std::string> split(std::string str, char delim);
// ...
for (auto pair : split(original_input_with_pipes, '|'))
{
// Here pair is a string containing values like "user1:192.168.0.1" etc.
auto values = split(pair, ':'); // Split each pair
// Now values[0] should be e.g. "user1"
// and values[1] should be "192.168.0.1"
}
答案 1 :(得分:0)
只需分割两次,首先用|
,然后(在每个结果上)用:
作为分隔符。这是一个非常有效且紧凑的拆分功能
std::vector<std::string> split(const std::string& text, const char separator)
{
std::vector<std::string> items;
std::istringstream f(text);
std::string s;
while (getline(f, s, separator)) {
items.push_back(s);
}
return items;
}
如果您确信关于定界符替代的事实,则可以通过交换定界符来构建专用功能,此处简称为demo:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
int main()
{
std::string text = "user1:192.168.0.1|user2:192.168.0.2|user3:192.168.0.3";
std::vector<std::pair<std::string, std::string> > pairs;
std::istringstream f(text);
std::string name, ip;
while (getline(f, name, ':')) {
if (getline(f, ip, '|')) {
pairs.push_back(std::pair<std::string,std::string>(name, ip));
} else {
break;
}
}
for (auto pair: pairs) {
std::cout << pair.first << ", " << pair.second << std::endl;
}
}
答案 2 :(得分:0)
您可以这样做:
std::vector<std::string> tokens;
boost::split(tokens, input, boost::is_any_of("|:."));
(然后,只需将令牌填充到您的结构中即可)
#include <boost/algorithm/string.hpp>
#include <iostream>
int main(){
auto input = "user1:192.168.0.1|user2:192.168.0.2|user3:192.168.0.3";
std::vector<std::string> tokens;
boost::split(tokens, input, boost::is_any_of("|:."));
for (auto tok : tokens) {
std::cout << tok << std::endl;
}
return 0;
}
std::regex
可以做同样的事情:
std::regex re("\\.;\\|");
std::sregex_token_iterator first{input.begin(), input.end(), re, -1}, last;//the '-1' is what makes it split
std::vector<std::string> tokens{first, last};
答案 3 :(得分:0)
您在这里。
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> splitStr( const std::string &s,
const std::string &delim = " \t" )
{
std::vector<std::string> v;
for ( std::string::size_type pos = 0, n = 0;
( pos = s.find_first_not_of( delim, pos ) ) != std::string::npos;
pos += n )
{
n = s.find_first_of( delim, pos );
n = ( n == std::string::npos ? s.size() : n ) - pos;
v.push_back( s.substr( pos, n ) );
}
return v;
}
int main()
{
const std::string s( "user1:192.168.0.1|user2:192.168.0.2|user3:192.168.0.3 " );
for ( const auto &item : splitStr( s, ":|" ) )
{
std::cout << item << std::endl;
}
return 0;
}
程序输出为
user1
192.168.0.1
user2
192.168.0.2
user3
192.168.0.3
也就是说,您可以使用类find_first_of
的搜索成员函数find_first_not_of
和std::string
。
您可以为该函数提供任何定界符。
答案 4 :(得分:0)
您可以使用正则表达式来执行复杂的字符串处理。与手工处理相比,维护和处理通常更容易。
lytickpos