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

罗索

char, wchar_t与STL的字符串格式化format

落鹤生 发布于 2011-02-12 14:38 点击:次 
最近一直在写序列化类,希望把一些游戏过程中的场景数据信息存储到硬盘。因为需要处理的数据很多,所以我写了一个工具类,其中包括字符串的序列化
TAG:

最近一直在写序列化类,希望把一些游戏过程中的场景数据信息存储到硬盘。因为需要处理的数据很多,所以我写了一个工具类,其中包括字符串的序列化,问题来了:
公司原先的代码参差不齐,有使用AString的(使用ANSI char作为字符单元,相当于std::string),也有考虑到unicode问题而采用AWString的(使用wchar_t作为字符单元,相当 于std::wstring),同时考虑到根据编译环境自动视别的问题,也定义有一个宏ACString,即:如果定义有UNICODE环境变量,则自动 替换为AWString,否则使用AString。好吧,自作聪明的我使用了ACString来写工具函数,测试时没有任何问题,但一旦加入到真正的运行 环境中就会出现“把const char*转化为bool,性能警告”的错误,几经检查,发现在游戏环境下,传入的参数是AString类型,而我用的ACString则被自动转化成了 AWString,找不到参数匹配的,所以只有默认转化了。
看来,解决办法只能是同时提供AString与AWString两种类型的工具函数,因为你不知道你的客户传给你的将是哪一种,除非大家都铁了心的一致使用ACString,然而在现实的编码中,这却是不切实际的。
这让我想起前两天为STL写的格式化函数(STL没有,只好自己写了-_-),当时我也想自作聪明的把std::string与std::wstring合二为一,现在想来恐怕是庸人自扰罢了,于是早上起来把原来的代码作下修改,如下:

  1. //details refer to http://www.rosoo.net/a/201012/10701.html 
  2. string RsFormat(const char* pszFormat, ...) { 
  3.     string strResult = ""
  4.     if (NULL != pszFormat) 
  5.     { 
  6.         va_list marker = NULL; 
  7.         va_start(marker, fmt);//初始化变量参数 
  8.         size_t nLength = _vscprintf(pszFormat, marker) + 1;//获取格式化字符串长度 
  9.         vector<char> vBuffer(nLength, '\0');//创建用于存储格式化字符串的字符数组 
  10.         int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength
  11. , pszFormat, marker); 
  12.         if (nWritten>0) 
  13.         { 
  14.             strResult = &vBuffer[0]; 
  15.         } 
  16.         va_end(marker);//重置变量参数 
  17.     } 
  18.  
  19.     return strResult; 
  20.  
  21. wstring RsFormat(const wchar_t *pszFormat, ...) { 
  22.     wstring strResult=L""
  23.     if (NULL != pszFormat) 
  24.     { 
  25.         va_list marker = NULL; 
  26.         va_start(marker, pszFormat);//初始化变量参数 
  27.         size_t nLength = _vscwprintf(fmt, marker) + 1;//获取格式化字符串长度 
  28.         vector<wchar_t> vBuffer(nLength, L'\0');//创建用于存储格式化字符串的字符数组 
  29.         int nWritten = _vsnwprintf_s(&vBuffer[0], vBuffer.size(), nLength
  30. , pszFormat, marker); 
  31.         if (nWritten > 0) 
  32.         { 
  33.             strResult = &vBuffer[0]; 
  34.         } 
  35.         va_end(marker);//重置变量参数 
  36.     } 
  37.     return strResult; 

测试全码(其中str.hpp就是上面代码的文件名了):

  1. #include <iostream> 
  2. #include <cassert> 
  3. #include "str.hpp" 
  4. int main(int argc, char* argv[]) 
  5.     const double PI=3.1415926; 
  6.     std::string s=str::format("ANSI%s---字符:%c;整数:%d;双精度:%f""测试",'a'
  7. , 38, PI); 
  8.     std::cout<<s<<std::endl; 
  9.  
  10.     std::wstring ws=str::format(L"UNICODE%s---字符:%c;整数:%d;双精度:%f", L"测试",'u'
  11. , 83, PI); 
  12.     std::wcout<<ws<<std::endl; 
  13.  
  14.     system("pause"); 
  15.     return 0; 

存在的问题:

   问题一:前面的format函数只能在vs2005下通过编译,在vc6.0下就不可以,原因是用于“获取格式化字符串长度”的_vscprintf和_vscwprintf在vc6.0中找不到替代品;
   问题二:相信大家已经看到了,ANSI字符串的测试没有任何问题,但UNICODE字符串在输出时中断了,确切的说是在输出到中文时中断了,我用断点查看 过,ws的构造没有问题,即wchar_t版的format函数没有问题,那么问题就应该出在std::wcout上面,但问题在哪呢?
   诸位看官,欢迎提供任何指导意见。

除此之外还有另一篇与此类似的文章,也可拿来作为参考:http://www.rosoo.net/a/201012/10701.html

(xmli)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201102/10870.html]
本文出处:cppblog.com/xmli 作者:xmli
顶一下
(3)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容