以下是我使用字符串标记符的方法。
typedef std::string string_t;
typedef std::vector<string_t> stations_t;
void Tokenize(const string_t& str, stations_t& tokens,const string_t& delimiters = " ") {
string_t::size_type lastPos = str.find_first_not_of(delimiters, 0);
string_t::size_type pos = str.find_first_of(delimiters, lastPos);
while (string_t::npos != pos || string_t::npos != lastPos){
tokens.push_back(str.substr(lastPos, pos - lastPos));
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
}
当我将字符串1,8003,1,HWH,Kolkata Howrah Junction,,16:10,,1,0
传递给此字段时,它会返回8
个字段,因为它应该返回9
,它完全忽略了,,
部分。任何人都可以看看,帮助我找到这里的错误。
答案 0 :(得分:2)
在您提供的示例中,您想要“16:10”和“1”之间的空字段,对吗?
你没有得到它的原因是因为当你得到子串“16:10”,那么pos
是43,你在那个位置找到一个不在分隔符字符串中的字符。第一个非分隔符是位置45处的“1”。
我建议这样的事情:
void Tokenize2(const string_t& str, stations_t& tokens,const string_t& delimiters = " ") {
string_t::size_type elem_start = 0;
string_t::size_type elem_end = str.find_first_of(delimiters, 0);
while (elem_start != string_t::npos && elem_end != string_t::npos) {
tokens.push_back(str.substr(elem_start, elem_end - elem_start));
elem_start = str.find_first_of(delimiters, elem_end) + 1;
elem_end = str.find_first_of(delimiters, elem_start);
}
if (elem_start != string_t::npos) {
// Get the last element
tokens.push_back(str.substr(elem_start, elem_end - elem_start));
}
}
答案 1 :(得分:1)
错误在于您找到令牌的逻辑。
lastPos = str.find_first_not_of(delimiters, 0);
pos = str.find_first_of(delimiters, lastPos);
基本上你试图找到一个不是分隔符的字符并将其分配给 lastPos ,然后继续在 lastPos 之后找到第一个分隔符并将其分配给< strong> pos 并抓住 lastPost 和 pos 之间的所有内容成为令牌。基本上,尝试查找 find_first_not_of 的行为将跳过任何连续的分隔符。您可以使用测试输入
,,,,,,,,22,
你会发现第一次迭代找到令牌 22 并跳过所有 连续“,”s
How do I tokenize a string in C++?有很多方法可以编写一个标记器