织梦CMS - 轻松建站从此开始!

罗索

编写一个STL 中的CString类

罗索客 发布于 2004-04-12 14:13 点击:次 
徐岩柏 br/2003-6-3 16:04:26br/ br/STL英文是Standard Template Library,也就是我们常说的C++标准模板库,。该标准库于1998年被正式纳入C++标准,给全世界的C++程序员带来了福音。最让我们兴奋的应该是它的跨平台性,使得你在WINDOW,UNIX ,LINUX等操作系统上面用标准C
TAG:

徐岩柏 <br/>2003-6-3 16:04:26<br/> <br/>STL英文是Standard Template Library,也就是我们常说的C++标准模板库,。该标准库于1998年被正式纳入C++标准,给全世界的C++程序员带来了福音。最让我们兴奋的应该是它的跨平台性,使得你在WINDOW,UNIX ,LINUX等操作系统上面用标准C++编写的程序不用修改即可移植。(当然要有C++的编译器)。<br/><br/>现在的编译器虽然对标准C++支持程度不同,单总体上还是很好。WINDOWS平台的VC ,BC,Linux/UNIX平台的g++都是一流的编译器,都支持STL。而且STL是有源代码的,你可以扩展增加,避开这些微小的不同。<br/><br/>说到STL首先要说的当然是字符串处理类std::string,这可能是一个程序员使用最多的一个类,它的功能强大,使用非常方便。但习惯于用VC的CString开发的编程人员会感到有点不方便。幸运的是这个不方便可以很容易的解决,方法就是对标准的字符串类std::string进行包装,生成一个类似Cstring的类,我把它命名为Xstring。<br/><br/>下面就从Format函数说起,这可能是大部分人最希望用到的:<br/><br/>本函数是一个变参函数,对参数不定的函数其各式如下:<br/><br/>int Format(const char* pstrFormat, ... )<br/><br/>其中pstrFormat是格式串,三个点代表所有的参数。格式中的每个格式和后面的参数必须相对应,否则函数的执行会出现意想不到的结果;当然过多的参数将被忽略。格式分为简单字符和转换规范字符两类。具体格式规范有如下格式:<br/><br/>%[flags] [width] [.precision] [{h | l | I64 | L}]type<br/><br/>flags是标志字符,输出对齐,尾零,数值符号,进制数(八或十六)<br/><br/>width是宽度规范符,填补空格或0的个数<br/><br/>precision是精度规范符,打印字符最多个数,对于整数值,为最少数字个数<br/><br/>h短整型数的输出<br/><br/>I长整型数的输出<br/><br/>I64为64位的整型输出<br/><br/>如果你对格式还不清楚,请参考有关printf的格式资料。<br/><br/>对不定参数的处理也很特殊,要使用下面的几个函数<br/><br/>先声明一个变量va_list argList;<br/><br/>va_start(argList,pstrFormat);<br/><br/>int cnt =vsprintf(buff, pstrFormat, argList);<br/><br/>va_end(argList);<br/><br/>这样就把格式化后的结果保存在buff字符串中了。<br/><br/><br/>然后最重要的就是计算这个buff有多大,如果大了就有内存浪费,小了完不成任务,所以要根据格式来动态计算,然后动态的开辟内存空间。就用一个循环来把格式串中的每一个字符读出来分别处理。先初始化一个长度变量nMaxLen =0;<br/><br/>for (const char * p = pstrFormat; *p != ''\\0'';p++ )<br/><br/>如果读出来的不是’%’或是‘%%’则长度加一。<br/><br/>if (*p != ''%'' || *(++p) == ''%'')<br/><br/>{<br/><br/>nMaxLen += 1;<br/><br/>continue;<br/><br/>}<br/><br/>如果前一个字符是‘%’,则读取格式,如果是‘#’则长度加2,来为‘0x’预留空间;如果是‘*’,则读紧跟着的一个整数,得到指定的宽度;其他的‘+’、‘-’、‘ ’、‘0’等字符主要是填充用,忽略长度。<br/><br/>for (; *p != ''\\0''; p ++)<br/><br/>{<br/><br/>if (*p == ''#'')<br/><br/>nMaxLen += 2; // 处理 ''0x''<br/><br/>else if (*p == ''*'')<br/><br/>nWidth = va_arg(argList, int); //如:''%5f'' 中的5<br/><br/>else if (*p == ''-'' || *p == ''+'' || *p == ''0''|| *p == '' '')<br/><br/>; //忽略该符号<br/><br/>else // 不是标志字符就退出循环<br/><br/>break;<br/><br/>}<br/><br/>如果下一个字符是‘.’则忽略去读取其后面一个字符,如果是‘*’则也要读出其后的宽度,来计算精度。<br/><br/>if (*p == ''*'')<br/><br/>{<br/><br/>nPrecision = va_arg(argList, int);<br/><br/>p ++;<br/><br/>}<br/><br/>else<br/><br/>{<br/><br/>nPrecision = atoi(p);<br/><br/>for (; *p != ''\\0'' && isdigit(*p); p ++)<br/><br/>;<br/><br/>}<br/><br/>接下来处理字符如果是‘h’、‘l’、‘I’、‘F’、‘N’等,则忽略计算长度。<br/><br/>如果读取字符是‘c’、‘C’则长度加上2(考虑宽字符的情况);如果读取的是‘s’、‘S’则要计算参数中给的字符串的宽度。<br/><br/>switch (*p)<br/><br/>{<br/><br/>case ''c'': <br/><br/>case ''C'':<br/><br/>nItemLen = 2;<br/><br/>va_arg(argList, char);<br/><br/>break;<br/><br/>case ''s'': // 字符串<br/><br/>case ''S'':<br/><br/>nItemLen = strlen(va_arg(argList, const char*));<br/><br/>nItemLen = ((1) > (nItemLen)) ? (1) : (nItemLen);//如果是空串就使用1 即保存''\\0''<br/><br/>break;<br/><br/>}<br/><br/>如果读出的字符是‘d’、‘i’、‘u’、‘x’、‘o’,‘e’、‘f’、‘G’、‘g’等,则长度加上对应的数值型的长度,当然最好使用sizeof计算,使得具有更好的移植能力。<br/><br/>case ''d'':<br/><br/>case ''i'':<br/><br/>case ''u'':<br/><br/>case ''x'':<br/><br/>case ''X'':<br/><br/>case ''o'':<br/><br/>va_arg(argList, int);<br/><br/>nItemLen = 32; <br/><br/>在for循环体的最后当然不要忘了把长度累计nMaxLen += nItemLen;当循环结束时,长度的计算也就完成了。<br/><br/>For循环结束时调用va_end(argList);<br/><br/>下面就可以开辟恰当的内存空间,来保存你的格式串。<br/><br/>char* ch = new char[nMaxLen+1]; <br/><br/>有了空间再重新接收参数就可以了。<br/><br/>va_start(argList, pstrFormat);<br/><br/>vsprintf(ch, pstrFormat, argList);<br/><br/>va_end(argList);<br/><br/>最后不要忘了把空间加到std::string中,可以直接调用append函数:<br/><br/>this->append(ch);<br/><br/>然后释放你的内存空间<br/><br/>delete[] ch;<br/><br/><br/>其他的函数可以用std::string中的相对应的功能包装即可,下面就再写一个MakeUpper函数,它也是CString中的。<br/><br/>void MakeUpper()<br/><br/>{<br/><br/>std::transform(this->begin (), <br/>this->end (),this->begin (),<br/>toupper);<br/><br/>}<br/><br/>是不是很容易呢,希望本文能起到抛砖引玉的作用,给你使用STL带来方便。<br/><br/>以上的程序编码在VC和g++中均可使用。本人曾用XString 类替代了一个用MFC编写的项目中的所有的CString类 ,使得它顺利的用G++编译通过。<br/><br/><br/>本用例的完整代码为stl.zip<IMG SRC="/sys_images/FileIcon/zip.gif" border='0'/> <a href='/Files/UpFiles/dev2/vc/0010297000_2004412_141313_72948.zip'>点击浏览该文件</a> (徐岩柏)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/200404/924.html]
本文出处: 作者:徐岩柏
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容