错过会难过 发表于 2016-1-22 23:44:00

一个仿CString的类,内置Format函数,通配符查找函数

本帖最后由 错过会难过 于 2016-1-22 23:45 编辑

4]仿照了以atl里头的CString 和 stl里头的string ,
功能大概有:

        CString 里的format函数
        这个函数太好使了, 所以写了一个出来,只实现了%s %S %x %X %d %lf

        string中类似 <<hex

        当然还有字符串搜索的通配符搜索, 主要支持 * 和 ? 通配符
       

具体代码实现文件: **** Hidden Message *****

Format函数

String& String::Format(const TCHAR* szFormat,...)
{
        /*
                ebp+4        : 返回值
                ebp+8        : this指针
                ebp+c        : 第一个形参
        */
        SIZE_T*        nParam = (SIZE_T*)&szFormat;// 第一个形参的地址

        SIZE_T        dwFormatLen = _tcslen(szFormat);

        Clear();


        SIZE_T          i = 0;
        SIZE_T        dwParam = 0;
        BOOL        bIsBack = 0;

        //        将格式化输入置零
        m_dwFormatFlag = 0;

        // 获取第二个形参
        ++nParam;

        while(i < dwFormatLen)
        {
                if(szFormat != '%' || bIsBack)
                {
                        operator<<((TCHAR)(szFormat));
                        bIsBack = FALSE;
                        ++i;
                }
                else
                {
                        switch(szFormat)
                        {
                                case 's': // %s
                                {
                                                        m_dwFormatFlag |= FORT_ONCE | FORT_LOWER;
                                                        operator+=((TCHAR*)(*(nParam++)));
                                                        ++i;
                                                        break;
                                }
                                case 'S':// %S
                                {
                                                        m_dwFormatFlag |= FORT_ONCE | FORT_UPPER;
                                                        operator+=((TCHAR*)(*(nParam++)));
                                                        ++i;
                                                        break;
                                }
                                case 'd':// %d
                                {
                                                       operator+=((int)(*nParam++));
                                                       ++i;
                                                       break;
                                }
                                case 'u':// %u
                                {
                                                       operator+=((SIZE_T)(*nParam++));
                                                       ++i;
                                                       break;
                                }
                                case 'x':// %x
                                {
                                                        m_dwFormatFlag |= FORT_ONCE | FORT_HEX | FORT_LOWER;
                                                        operator+=((SIZE_T)(*nParam++));
                                                        ++i;
                                                        break;
                                }
                                case 'X':// %X
                                {
                                                        m_dwFormatFlag |= FORT_ONCE | FORT_HEX | FORT_UPPER;
                                                        operator+=((SIZE_T)(*nParam++));
                                                        ++i;
                                                        break;
                                }
                                case 'l':
                                {
                                                        if(szFormat == 'f')// %lf
                                                        {
                                                                operator+=((double)*((double*)nParam));
                                                                nParam = (SIZE_T*)((LPBYTE)nParam+sizeof(double));// double占用8位
                                                                ++i;
                                                        }
                                                        ++i;
                                                        break;
                                }
                                default:
                                {
                                                   --i;
                                                   bIsBack = TRUE;
                                }
                                break;
                        }
                        ++i;
                }
        }
       
        return        *this;
}

       

通配符查找函数 : Find
// 形参 : const LPBYTE lpSrcBuff
// 形参 : SIZE_T dwSrcSize
// 形参 : const LPBYTE lpDesBuff
// 形参 : SIZE_T dwDesSize
//*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*
int String::Find(const TCHAR* pwzSrcBuff, /* 查找目标 */
                                   SIZE_T dwSrcSize,      /* 目标字符个数 */
                                   const TCHAR* pwzDesBuff, /* 要查找的字符串 */
                                   SIZE_T dwDesSize/* 要查找字符串字符个数 */
                                   )
{


        if(pwzSrcBuff == NULL || pwzDesBuff == NULL)
        {
                return -1;
        }
        if(dwSrcSize == 0 || dwDesSize == 0)
        {
                return -1;
        }
               
        SIZE_T        i = 0; // 父串的迭代器
        SIZE_T        j = 0; // 子串的迭代器
       

        int        nDesEnd = 0;
        while(i<dwSrcSize)
        {
                if(j >= dwDesSize) // 全匹配
                {
                        return (int)(i - dwDesSize - nDesEnd); // 返回位置
                }

                // 判断是否允许两字符相等
                //        相等条件一: 子串的一个字符如果是 反斜杠: \
                //        则用反斜杠后的字符 和 父串的当前字符进行比较
                //        相等条件二: 子串的当前字符如果是特殊符号,
                //        则判断父串后续字符中有没有特殊符号后的字符.

                // 检查子串的当前字符是不是反斜杠或特殊字符
                if(pwzDesBuff == '\\')
                {
                        if(pwzDesBuff == '*'
                           || pwzDesBuff == '?'
                          )
                        {
                                --nDesEnd;
                                ++j;
                        }
                }
                else if (pwzDesBuff=='*')
                {
                        // 判断在下一个特殊符号前,父串有没有子串中*号后的那个字符

                        // 在父串的当前符号到最后一个符号区间,查找子串中*号后的那个字符
                        int nPos = 0;

                        // 如果下一个符号是* 或 ? ,则直接跳过
                        // 如果下一个字符已经到达子串的尽到,则可以返回
                        while(pwzDesBuff == '?' || pwzDesBuff=='*')
                        {
                                ++i;// 指向父串的下一个
                                ++j;// 指向子串的下一个
                                // 忽略掉*字符
                                if(pwzDesBuff == '*')
                                        --nDesEnd;

                                if(j >= dwDesSize)
                                {
                                        // -1 : 忽略*字符
                                        return (int)(i - dwDesSize - nDesEnd);
                                }
                        }

                        // 得到*号后的一个符号 , 在父串中查找其位置
                        ++j;
                        // 保证这个字符没有到达子串末尾
                        if(j >= dwDesSize)
                        {
                                return (int)(++i - dwDesSize - nDesEnd);
                        }

                        // 找到*字符后的字符
                        nPos = Find(pwzSrcBuff + i,dwSrcSize - i,pwzDesBuff);
                        // 如果没有找到则直接返回没有匹配的字符串
                        if(nPos < 0)
                                return -1;
                       
                        // 如果找到了, nPos就是以i为基址的偏移
                        i += nPos;

                        // 经过* 通配之后,子串的长度需要膨胀,-1是忽略特殊符号: *
                        nDesEnd += nPos-1;
                       
                }
                else if (pwzDesBuff=='?')
                {
                        // 忽略一个字符
                        ++i;
                        ++j;
                        continue;
                }


                // 判断父串的当前字符 和 子串的当前字符是否相等
                if(pwzSrcBuff == pwzDesBuff)
                {
                        ++j;
                }
                else if(j>0&&pwzSrcBuff != pwzDesBuff)
                {
                        j = 0;
                        continue;
                }

                ++i;
        }


        return -1;
}

xfhxfh 发表于 2017-8-30 15:51:04

{:10_277:}学习
页: [1]
查看完整版本: 一个仿CString的类,内置Format函数,通配符查找函数