如何使用两个不同的分隔符分割字符串

时间:2019-09-26 12:29:50

标签: c++ string vector split substring

我想将数据存储在对象数组中,但是我不知道如何分割字符串。

我希望看到的结果是:

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);
}

感谢前进

5 个答案:

答案 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("|:."));    

(然后,只需将令牌填充到您的结构中即可)


Try it yourself !

#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_ofstd::string

您可以为该函数提供任何定界符。

答案 4 :(得分:0)

您可以使用正则表达式来执行复杂的字符串处理。与手工处理相比,维护和处理通常更容易。

lytickpos