WideCharToMutiByte出现中文乱码

这个小问题困了我一天一夜了,本来今天都计划写XML处理的代码了,结果又耽搁了一天。幸好后头还搞出来了。

我想写个程序,通过SOCKET获得服务器的XML文件,然后保存到本地。获取文件是搞定了,但是保存成文件时老出现乱码。

以下是会出现乱码的代码片断:

void CTecClientDlg::OnBnClickedbtnlogin()
{
    // TODO: 登陆按钮,登陆后下载数据。
   WORD version;
   WSADATA wsaData;
   int rVal=0;
   version=MAKEWORD(1,1);
   WSAStartup(version,(LPWSADATA)&wsaData); 
   SOCKET theSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   if(theSocket==SOCKET_ERROR)
   {
       return;
   }
   SOCKADDR_IN serverInfo;
   serverInfo.sin_family=PF_INET;
   serverInfo.sin_addr.s_addr=inet_addr("192.168.0.3");
   serverInfo.sin_port=htons(6603);
   rVal=connect(theSocket,(LPSOCKADDR)&serverInfo,sizeof(serverInfo));
   if(rVal==SOCKET_ERROR)
   {
       return;
   }
   //==========================关键是这个片段
   CFile xmlFile(_T("Data.xml"),CFile::modeCreate|CFile::modeWrite);  
   wchar_t buf[200]; 
   int strLast=0;
   do{
        memset(buf,0,200*sizeof(wchar_t));
        strLast=recv(theSocket,(char*)buf,200*sizeof(wchar_t),0);
        if(strLast<=0)
        {//如果读取的长度不正常,退出循环。
            break;
        }  
        //倒数第三个参数为0,函数功能变为:返回buf的char类型容量。下面才好动态分配一个char*的内存空间。
        DWORD charLen=WideCharToMultiByte(CP_UTF8,0,buf,-1,NULL,0,NULL,FALSE);
        char* MutiByteBuf;
        MutiByteBuf=new char[charLen];
        WideCharToMultiByte(CP_UTF8,0,buf,-1,MutiByteBuf,charLen,NULL,FALSE);        
        xmlFile.Write(MutiByteBuf,charLen);      
        delete [] MutiByteBuf;  
   }while(strLast>0);
   xmlFile.Close();
   closesocket(theSocket);
   WSACleanup();
}

过程很辛苦,但结果很简单。

TIP:WideCharToMultiByte的第四个参数为-1,那么第三个参数buf的长度就是buf内容长度+一个NULL。

就是因为加的这个NULL导致我的程序在第二次循环后,时不时的出现乱码,非常恼火。

下面是可以正常工作的代码。

void CTecClientDlg::OnBnClickedbtnlogin()
{
    // TODO: 登陆按钮,登陆后下载数据。
   WORD version;
   WSADATA wsaData;
   int rVal=0;
   version=MAKEWORD(1,1);
   WSAStartup(version,(LPWSADATA)&wsaData);
   SOCKET theSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   if(theSocket==SOCKET_ERROR)
   {
       return;
   }
   SOCKADDR_IN serverInfo;
   serverInfo.sin_family=PF_INET;
   serverInfo.sin_addr.s_addr=inet_addr("192.168.0.3");
   serverInfo.sin_port=htons(6603);
   rVal=connect(theSocket,(LPSOCKADDR)&serverInfo,sizeof(serverInfo));
   if(rVal==SOCKET_ERROR)
   {
       return;
   }
   CFile xmlFile(_T("Data.xml"),CFile::modeCreate|CFile::modeWrite);
   wchar_t buf[200];
   int strLast=0;
   do{
        memset(buf,0,200*sizeof(wchar_t));
        strLast=recv(theSocket,(char*)buf,200*sizeof(wchar_t),0);
        if(strLast<=0)
        {
            break;
        }
       /**

          *

          *就是这个地方,第四个参数我没有使用-1,而是使用了精确的长度 strLast/2,这样就不会在末尾追加了。

          *下面一处的调用也是一样的。

        **/
        DWORD charLen=WideCharToMultiByte(CP_UTF8,0,buf,strLast/2,NULL,0,NULL,FALSE);
        char* MutiByteBuf;
        MutiByteBuf=new char[charLen];
        WideCharToMultiByte(CP_UTF8,0,buf,strLast/2,MutiByteBuf,charLen,NULL,FALSE);
        xmlFile.Write(MutiByteBuf,charLen);
        delete [] MutiByteBuf; 
   }while(strLast>0);  
   xmlFile.Close(); 
   closesocket(theSocket);
   WSACleanup();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值