不会飞的鸟

2010年12月10日 ... 不鸟他们!!! 我要用自己开发的分布式文件系统、分布式调度系统、分布式检索系统, 做自己的搜索引擎!!!大鱼有大志!!! ---杨书童

【转】STL_string的字符串替换函数

标准C++中的string中的函数不多,没有CString的功能强大,但是如果想在Unicode编码下使用多字节,就不能使用CString,于是自己写了一个类似于CString的Replace函数。
string replace( const string& inStr, const char* pSrc, const char* pReplace )
{
     string str = inStr;
    string::size_type stStart = 0;
    string::iterator iter = str.begin();
    while( iter != str.end() )
    {
        // 从指定位置 查找下一个要替换的字符串的起始位置。
        string::size_type st = str.find( pSrc, stStart );
        if ( st == str.npos )
        {
            break;
        }
        iter = iter + st - stStart;
        // 将目标字符串全部替换。
        str.replace( iter, iter + strlen( pSrc ), pReplace );
        iter = iter + strlen( pReplace );
        // 替换的字符串下一个字符的位置
        stStart = st + strlen( pReplace );
    }
    return str;
}

上述方法在执行replace( "h h h h h h h h h h h h h h h h h h h ", " ", " " )时出现问题。
下面再列出一种方法:
string CComFunc::replace( const string& inStr, const char* pSrc, const char* pReplace )
{
    string strSrc = inStr;
    string::size_type pos=0;      
    string::size_type srclen = strlen( pSrc );       
    string::size_type dstlen = strlen( pReplace );       
    while( (pos=strSrc.find(pSrc, pos)) != string::npos)
    {               
        strSrc.replace(pos, srclen, pReplace);               
        pos += dstlen;       
    }
    return strSrc;
}

补充,经过测试,上面方法再执行,replace( “暴”, "\\","==" )时,依然会遇到问题。
在日文系统上,因为“暴”占两个字节,而"\\"只占一个字节,但与“暴”的低位字节ASCII码相同。
而string的Find函数,是按照字节比较的,所以,将这个字节替换了,导致文本替换出现问题。
于是考虑到不应该按字节比较,应该按字符比较,测试发现,CString的替换函数没有问题,于是考虑按照CString的方法重新写一个replace函数。
代码如下:
因为CString在_MBCS和_UNICODE下是变宽的,而我写的replace函数,只针对string。
string CComFunc::replace( const string& inStr, const char* pSrc, const char* pReplace )
{
    string strSrc = inStr;
    LPSTR lpch = ( CHAR* )strSrc.c_str();
    int   nOldLength = strlen( lpch );
    int    nSourceLen = strlen(pSrc);
    if (nSourceLen == 0)
    {
        return lpch;
    }
    int   nReplacementLen = strlen(pReplace);
    LPSTR lpszStart = lpch;
    LPSTR lpszEnd = lpszStart + nOldLength;
    LPSTR lpszTarget;

    // 先列出判断替换字符是否存在的方法, 但在此函数中不使用这段代码。
/*
    // judge whether exist
    while (lpszStart < lpszEnd)
    {
        while ((lpszTarget = (CHAR*)_mbsstr(( const unsigned char * )lpszStart, ( const unsigned char * )pSrc)) != NULL)
        {
            nCount++;
            lpszStart = lpszTarget + nSourceLen;
        }
        lpszStart += strStart.length() + 1;
    }
    *//
   
    // 下面是替换的代码。
    while (lpszStart < lpszEnd)
    {
        while ((lpszTarget = (CHAR*)_mbsstr(( const unsigned char * )lpszStart, ( const unsigned char * )pSrc)) != NULL)
        {
            int nBalance = nOldLength - (lpszTarget - lpch + nSourceLen);
            memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
                nBalance * sizeof(CHAR));
            memcpy(lpszTarget, pReplace, nReplacementLen*sizeof(CHAR));
            lpszStart = lpszTarget + nReplacementLen;
            lpszStart[nBalance] = '\0';
            nOldLength += (nReplacementLen - nSourceLen);
        }
        lpszStart += strlen(lpszStart) + 1;
    }
    return lpch;
}

此方法最关键的是_mbsstr函数,在"MBSTRING.H"头文件中声明。

posted on 2012-10-26 16:20 不会飞的鸟 阅读(1413) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理