【问题标题】:Implementing tokenize function with CString用 CString 实现 tokenize 函数
【发布时间】:2018-09-25 01:52:15
【问题描述】:

为了学习,我正在尝试用 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??。 我的想法用完了,如果有人能解决这个问题,我将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    如果找到分隔符 (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
    }
    

    【讨论】:

    • 感谢您的帮助!现在可以正常运行了。希望我将来能够看到并纠正自己的愚蠢错误。
    • 没问题。我进行了编辑以使代码更易于理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    相关资源
    最近更新 更多