使用CString实现tokenize函数

时间:2018-04-15 04:13:35

标签: c++11 visual-c++ mfc c-strings

为了学习,我正在尝试用CStrings实现我自己的简单Tokenize函数。我目前有这个文件:

11111
22222
(ENDWPT)


222222
333333
(ENDWPT)
6060606
ggggggg
hhhhhhh
(ENDWPT)
iiiiiii
jjjjjjj
kkkkkkk
lllllll
mmmmmmm
nnnnnnn

我希望用分隔符(ENDWPT)对其进行标记。 我编写了以下函数,它试图找到分隔符位置,然后添加分隔符长度并将文本提取到此位置。之后,更新一个使用的计数器,以便下次调用该函数时,它开始从上一个索引中搜索分隔符。该函数如下所示:

bool MyTokenize(CString strText, CString& strOut, int& iCount)
{
    CString strDelimiter = L"(ENDWPT)";
    int iIndex = strText.Find(strDelimiter, iCount);

    if (iIndex != -1)
    {
        iIndex += strDelimiter.GetLength();
        strOut = strText.Mid(iCount, iIndex);
        iCount = iIndex;
        return true;
    }
    return false;
}

正如这样被召唤:

int nCount = 0;

while ((MyTokenize(strText, strToken, nCount)) == true)
{
    // Handle tokenized strings here
}

现在,该函数以错误的方式拆分字符串,我认为这是因为Find()可能返回错误的索引。我认为它应该返回12,但它实际上是返回14 ?? 我没有想法,如果有人能解决这个问题,我会非常感激。

1 个答案:

答案 0 :(得分:2)

如果找到分隔符(iIndex),则从(iIndex - iCount)开始读取iCount计数。然后修改iCount

if(iIndex != -1)
{
    strOut = strText.Mid(iCount, iIndex - iCount);
    iCount = iIndex + strDelimiter.GetLength();
    return true;
}

源字符串可能不以分隔符结尾,它需要一个特殊情况。

您还可以选择更好的名称以匹配CString::Mid(int nFirst, int nCount)的使用情况,以便更容易理解。 MFC使用camelCase编码样式,在变量前面有类型标识符,这在C ++中是不必要的,我将在此示例中避免使用它:

bool MyTokenize(CString &source, CString& token, int& first)
{
    CString delimeter = L"(ENDWPT)";
    int end = source.Find(delimeter, first);

    if(end != -1)
    {
        int count = end - first;
        token = source.Mid(first, count);
        first = end + delimeter.GetLength();
        return true;
    }
    else
    {
        int count = source.GetLength() - first;
        if(count <= 0)
            return false;

        token = source.Mid(first, count);
        first = source.GetLength();
        return true;
    }
}

...

int first = 0;
CString source = ...
CString token;
while(MyTokenize(source, token, first))
{
    // Handle tokenized strings here
}