拆分字符串时C ++不完整的输出

时间:2016-10-09 06:52:06

标签: c++ string vector split

我试图从字符串中提取某些数据,如下所示:

2833ae7~2be;2833ae8~2272

我想要做的是首先用冒号拆分它,然后每条记录,找到它是否包含2be然后用~2be拆分包含它的记录,然后再给我一个值~2be

我做了一些文章,这段代码就是这样做的,但问题是它没有给我全部输出:

#include <string>
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;

vector<string> split(string str,string sep){
    char* cstr=const_cast<char*>(str.c_str());
    char* current;
    vector<string> arr;
    current=strtok(cstr,sep.c_str());
    while(current!=NULL){
        arr.push_back(current);
        current=strtok(NULL,sep.c_str());
    }
    return arr;
}

int main(){
string items = "2833ae7~2be;2833ae8~2272";
vector<string> food = split(items, ";");
for(unsigned int i = 0; i < food.size(); i++)
{
    if(food[i].find("2be") != string::npos)
    {
        vector<string> arr = split(food[i],"~2be");


        cout << "Output ("<< i << ") = " << arr[0] << endl;

        }// end if

}// end for

    return 0;
}// end main

我得到的输出是:

Output <0> = 833a

应该是:

Output <0> = 2833ae7

我做错了什么?

1 个答案:

答案 0 :(得分:0)

正如其他人在评论中提到的那样,修改从std::string::c_str()获得的字符数组是未定义的行为。 strtok()修改其参数以标记令牌,因此您无法在此处使用它。

通过单个字符分隔符拆分std::string并不难。你可以这样做的一种方式是:

std::vector<std::string> split(const std::string &input, std::string::value_type delim)
{
    std::stringstream ss(input);
    std::vector<std::string> tokens;
    std::string token;
    while (std::getline(ss, token, delim))
    {
        tokens.push_back(token);
    }

    return tokens;
}

然后您可以像这样拆分字符串:

std::vector<std::string> tokens = split("2833ae7~2be;2833ae8~2272", ';');

这将为您提供一个包含两个元素的向量:&#34; 2833ae7~2be&#34;和&#34; 2833ae8~2272&#34;。

现在对于第二部分,您不能使用相同的split()方法,因为它仅适用于单字符分隔符。但你可以这样做:

for (std::size_t index = 0; index < tokens.size(); ++index)
{
    if (tokens[index].find("2be") != std::string::npos)
    {
        std::string::size_type pos = tokens[index].find("~2be");

        std::cout << "Output (" << index << ") = " << tokens[index].substr(0, pos) << "\n";
    }
}

使用相同的想法,您也可以尝试重写split()方法,使其适用于字符串分隔符,而不仅仅是像我的版本那样的单字符。