【发布时间】:2016-10-09 06:52:06
【问题描述】:
我试图从这样的字符串中提取某些数据:
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
我做错了什么?
【问题讨论】:
-
第一个问题是您在
std::string对象上使用了C 字符串函数。c_str中的c代表 constant。不应修改数据。来自thisc_strreference:“写入通过 c_str() 访问的字符数组是未定义的行为。”而strtok函数写入 到字符串。你必须做一个const_cast应该表明你做了一些你不应该做的事情。 -
您错误地使用了
strtok。该函数的第二个参数是一个字符串,其中包含将用作标记的分隔符集。当您将"~2be"传递给函数时,它会尝试在第一个参数中查找任何这些字符。当第一个参数为"2833ae7"时,它将在第一个2处中断并返回一个空字符串。 -
current=strtok(cstr,sep.c_str())-- 未定义的行为。strtok改变传递给它的数据,cstr指向const char *。 -
作为替代:
std::vector<char> cstr(str.begin(), str.end()); cstr.push_back(0);然后strtok(cstr.data(), sep.c_str())。