错误的分词

Erroneous tokenizing

本文关键字:分词 错误      更新时间:2023-10-16

我有这样的代码:

#include <boost/tokenizer.hpp>
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
int main() {
    using namespace std;
    boost::char_separator<char> sep(",");
    string s1 = "hello, world";
    tokenizer tok1(s1, sep);
    for (auto& token : tok1) {
        cout << token << " ";
    }
    cout << endl;
    tokenizer tok2(string("hello, world"), sep);
    for (auto& token : tok2) {
        cout << token << " ";
    }
    cout << endl;
    tokenizer tok3(string("hello, world, !!"), sep);
    for (auto& token : tok3) {
        cout << token << " ";
    }
    cout << endl;
    return 0;
}

该代码产生如下结果:

hello  world 
hello  
hello  world  !!

显然,第二行是错误的。我期待的是hello world。有什么问题吗?

标记器不会创建您作为第一个参数传递给其构造函数的字符串的副本,也不会在构造时计算所有标记,然后缓存它们。令牌提取是按需以惰性方式执行的。

然而,为了使这成为可能,只要提取令牌,执行令牌提取的对象必须保持存活。

在这里,当tok2的初始化结束时,要从中提取令牌的对象将超出作用域(同样适用于tok3)。这意味着当标记器对象尝试对该字符串使用迭代器时,您将得到未定义的行为

注意,tok3完全是偶然地给您期望的输出。期望的输出确实是具有未定义行为的程序的可能输出之一。