C/C++中的快速字符串标记化

mmh*_*hmm 1 c c++ string visual-studio-2010 tokenize

我正在开发一个C/C++应用程序(在Visual Studio 2010中),我需要对逗号分隔的字符串进行标记,我希望它尽可能快.目前我正在使用strtok_s.我跑了一些测试strtok_s对比sscanf,它似乎就像strtok_s是快(除非我写了一个可怕的实现:)),但我想知道如果任何人都可以提出一个更快的替代方案.

ild*_*arn 6

对于纯粹的运行速度,提升.精神.是一个很好的候选人.


Joh*_*ing 5

你能做的最好的事情是确保你只通过一次字符串,并即时构建输出。开始将字符提取到临时缓冲区中,当遇到分隔符时,将临时缓冲区保存到输出集合中,清除临时缓冲区,冲洗并重复。

这是执行此操作的基本实现。

template<class C=char>
struct basic_token
{
    typedef std::basic_string<C> token_string;
    typedef unsigned long size_type;
    token_string token_, delim_;
    basic_token(const token_string& token, const token_string& delim = token_string());
};

template<class C>
basic_token<C>::basic_token(const token_string& token, const token_string& delim)
:   token_(token),
    delim_(delim)
{
}

typedef basic_token<char> token;

template<class Char, class Iter> void tokenize(const std::basic_string<Char>& line, const Char* delims, Iter itx)
{
    typedef basic_token<Char> Token;
    typedef std::basic_string<Char> TString;

    for( TString::size_type tok_begin = 0, tok_end = line.find_first_of(delims, tok_begin);
        tok_begin != TString::npos; tok_end = line.find_first_of(delims, tok_begin) )
    {
        if( tok_end == TString::npos )
        {
            (*itx++) = Token(TString(&line[tok_begin]));
            tok_begin = tok_end;
        }
        else
        {
            (*itx++) = Token(TString(&line[tok_begin], &line[tok_end]), TString(1, line[tok_end]));
            tok_begin = tok_end + 1;
        }
    }
}

template<class Char, class Iter> void tokenize(const Char* line, const Char* delim, Iter itx)
{
    tokenize(std::basic_string<Char>(line), delim, itx);
}
template<class Stream, class Token> Stream& operator<<(Stream& os, const Token& tok)
{
    os << tok.token_ << "\t[" << tok.delim_ << "]";
    return os;
}
Run Code Online (Sandbox Code Playgroud)

...你会像这样使用:

string raw = "35=BW|49=TEST|1346=REQ22|1355=2|1182=88500|1183=88505|10=087^";
vector<stoken> tokens;
tokenize(raw, "|", back_inserter(tokens));
copy(tokens.begin(), tokens.end(), ostream_iterator<stoken>(cout, "\n"));
Run Code Online (Sandbox Code Playgroud)

输出是:

35=BW   [|]
49=TEST [|]
1346=REQ22      [|]
1355=2  [|]
1182=88500      [|]
1183=88505      [|]
10=087^ []
Run Code Online (Sandbox Code Playgroud)