• UNICODE问题


    VC中使用Unicode的一些列问题
    VC6.0中默认的是多字节编码,而自从VS2005以后都是默认的Unicode字符编码格式了。至于ANSI, MBCS(多字节编码)和UNICODE之间的区别可以百度一下。下面的一篇博文写的也比较详细:
    http://www.tongji.net/index.php/uid-160994-action-viewspace-itemid-12415
    大致说来:我们用C语言写的控制台程序里面大多都是多自己编码,其中英文字母是一个字节,中文是两个字节。而Unicode编码中英文和中文全是占两个字节。VC中用Unicode编码的一个好处就是MFC做的界面可以是操作系统的界面了(VC2008中还可以用更多的界面)。改用多字节编码的时候界面就是VC6.0里面那种98风格的界面了。这只是一个原因,更重要的原因是统一标准的问题,所以使用Unicode还是必要的。
    之前用 VC2008写程序的时候,在字符串前加_T就行了,例如:_T("呵呵呵!")就表示编译时看情况将字符串"呵呵呵!"转化为Unicode或者多字符编码格式。而L"呵呵呵!"表示将字符串"呵呵呵!"转换成Unicode。如今出现一个比较麻烦的问题,就是将Unicode的CString转换成 char[],主要是socket编程中sendto函数中遇到的。
    参考一篇博文:http://cj0000.itpub.net/post/4086/483973
    最后的代码如下:

     1 //------------------------- 全局函数---------------------------
     2 
     3 //将Unicode的 CString转换为多字节字符数组
     4 string WideCharToMultiChar(wstring str)
     5 {
     6     string return_value;
     7     //获取缓冲区的大小,并申请空间,缓冲区大小是按字节计算的
     8     int len = WideCharToMultiByte(CP_ACP, 0, str.c_str(), str.size(), NULL, 0, NULL, NULL);
     9     char *buffer = new char[len+1];
    10     WideCharToMultiByte(CP_ACP, 0, str.c_str(), str.size(), buffer, len, NULL, NULL);
    11     buffer[len] = '';
    12     //删除缓冲区并返回值
    13     return_value.append(buffer);
    14     delete [] buffer;
    15     return return_value;
    16 }
    17 //------------------------- 全局函数---------------------------
    18 
    19 void CChatDlg::OnBnClickedButtonSend()
    20 {
    21     // TODO: 在此添加控件通知处理程序代码
    22     //获取对方IP
    23     DWORD dwIP;
    24     ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);
    25 
    26     SOCKADDR_IN addrTo;
    27     addrTo.sin_family = AF_INET;
    28     addrTo.sin_port = htons(6000);
    29     addrTo.sin_addr.S_un.S_addr = htonl(dwIP);
    30 
    31     CString strSend;
    32     string tempSend;
    33     //获取待发送数据
    34     GetDlgItemText(IDC_EDIT_SEND, strSend);
    35     //在Unicode下将CString转换成char*
    36     tempSend = WideCharToMultiChar((LPCTSTR)strSend);
    37     //发送数据
    38     sendto(m_socket, tempSend.c_str(), tempSend.length()+1, 0, (SOCKADDR*)&addrTo, sizeof(SOCKADDR));
    39     //清空发送框的内容
    40     SetDlgItemText(IDC_EDIT_SEND, _T(""));
    41 }

    转换的时候比较重要的就是字符串中字符个数和字符串的结尾符号。
    最后运行的比较成功。
    另外,MSDN上有篇文章也很好,可以参考一下:http://msdn.microsoft.com/en-us/library/ms235631.aspx
    还有一种方法将CString转换成char*,而前面的方法只能将CString通过string.c_str()转换成const char*。

     1 #include <afxconv.h>
     2 CString strSend;
     3 int len;
     4 GetDlgItemText(IDC_EDIT_SEND, strSend);
     5 
     6 #ifdef _UNICODE
     7     //CString转换成char*
     8     USES_CONVERSION;
     9     wsabuf.buf = W2A(strSend);
    10     wsabuf.len = strlen(wsabuf.buf)+1;
    11 #else
    12     len = strSend.GetLength();
    13     wsabuf.buf = strSend.GetBuffer(len);
    14     wsabuf.len = len+1;
    15 #endif

    而在将char*转换成CString很方便:

    char buf[200];
    CString str(buf);

  • 相关阅读:
    JVM启动参数小结
    Java 线程池学习
    myeclipse 8.5安装freemarker插件方法
    开源文件比较工具:WinMerge、KDiff3、diffuse
    初探淘宝技术构架
    Java获取IP地址:request.getRemoteAddr()注意
    Spring MVC 教程,快速入门,深入分析
    分布式服务框架 Zookeeper -- 管理分布式环境中的数据
    YARN作业提交流程剖析
    经典的MapReduce1解析
  • 原文地址:https://www.cnblogs.com/yiyi-xuechen/p/3452231.html
Copyright © 2020-2023  润新知