字符串标记器失败

string tokenizer failing

本文关键字:失败 字符串      更新时间:2023-10-16

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

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,它完全忽略了,,部分。有没有人能帮我看看这个bug

在您提供的示例中,您希望在"16:10"answers"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));
    }
}

这个bug是在你寻找一个令牌的逻辑中。

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

基本上,您尝试找到一个不是分隔符的字符,并将其分配给lastPos,然后继续查找lastPos之后的第一个分隔符,并将其分配给pos,并抓住lastPostpos之间的所有内容作为令牌。基本上,尝试查找find_first_not_of的行为将跳过任何连续分隔符。您可以使用测试输入

,,,,,,,,22,

,您会发现第一次迭代找到令牌22并跳过所有连续"、"s

如何在c++中标记字符串?有很多方法来编写标记器