字符串标记符失败

时间:2011-12-12 07:13:47

标签: c++ stl

以下是我使用字符串标记符的方法。

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 个答案:

答案 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++?有很多方法可以编写一个标记器