2011-12-12 37 views
1

以下是我如何使用字符串标记器。字符串标记器失败

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,它是完全忽略,,一部分。任何人都可以看看,并帮助我找到这里的错误。

回答

2

在你提供的例子中,你需要一个在“16:10”和“1”之间的空字段,对吧?

你没有得到它的原因,是因为当你得到子字符串“16:10”,那么pos是43,并且你寻找一个字符不在从该位置开始的分隔字符串中。第一个非分隔符是“1”的位置45

我建议是这样的:

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

这个错误在于你找到一个令牌的逻辑。

lastPos = str.find_first_not_of(delimiters, 0); 
pos  = str.find_first_of(delimiters, lastPos); 

基本上你试图找到一个字符不是一个分隔符,并将其分配给lastPos,这样就可以进行后lastPos找到第一个分隔符,并将其分配给POS抢之间的一切lastPostpos是一个令牌。基本上,试图找到find_first_not_of的行为将跳过任何连续的分隔符。您可以使用测试输入

,,,,,,,,22, 

,你会发现,第一次迭代找到令牌,并跳过所有 连续“” S

How do I tokenize a string in C++?有很多的方式来写一个标记