鱼C论坛

 找回密码
 立即注册
查看: 3663|回复: 1

[技术交流] 一个仿CString的类,内置Format函数,通配符查找函数

[复制链接]
发表于 2016-1-22 23:44:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

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

        string中类似 <<hex

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

       

具体代码实现文件:
游客,如果您要查看本帖隐藏内容请回复


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[i] != '%' || bIsBack)
                {
                        operator<<((TCHAR)(szFormat[i]));
                        bIsBack = FALSE;
                        ++i;
                }
                else
                {
                        switch(szFormat[i+1])
                        {
                                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[i + 2] == '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[j] == '\\')
                {
                        if(pwzDesBuff[j + 1] == '*' 
                           || pwzDesBuff[j + 1] == '?'
                          )
                        {
                                --nDesEnd;
                                ++j;
                        }
                }
                else if (pwzDesBuff[j]=='*')
                {
                        // 判断在下一个特殊符号前,父串有没有子串中*号后的那个字符

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

                        // 如果下一个符号是* 或 ? ,则直接跳过
                        // 如果下一个字符已经到达子串的尽到,则可以返回
                        while(pwzDesBuff[j+1] == '?' || pwzDesBuff[j+1]=='*')
                        {
                                ++i;  // 指向父串的下一个
                                ++j;  // 指向子串的下一个
                                // 忽略掉*字符
                                if(pwzDesBuff[j + 1] == '*') 
                                        --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[j]);
                        // 如果没有找到则直接返回没有匹配的字符串
                        if(nPos < 0)
                                return -1;
                        
                        // 如果找到了, nPos就是以i为基址的偏移
                        i += nPos;

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


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

                ++i;
        }


        return -1;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-8-30 15:51:04 | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-28 14:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表