C/C++语言使用Unicode的方法
acmilan2015/04/02软件综合 IP:四川
一、在C/C++控制台应用程序中使用Unicode的方法

可能很多人都知道C/C++中Unicode字符串是wchar_t*,Unicode字符串常量是L"string",但是通常没办法在console中直接输出这些字符串,因为C/C++默认的设置是locale="C"(C区域),不支持Unicode字符串。
其实在C/C++中输出Unicode字符串很简单,只要重新设置一下区域,将区域设置为locale=""(当前区域)就可以了。不要混用C和C++输出,否则可能会导致失效。

C语言中的做法:
<code class="lang-cpp">#include <locale.h>
#include <wchar.h>
                                   
int main()
{
    // 应用环境Locale设置
    setlocale(LC_CTYPE,setlocale(LC_ALL,""));
                                   
    wprintf(L"万国码C语言\n");
                                   
    return 0;
}</wchar.h></locale.h></code>

C++语言的做法:
<code class="lang-cpp">#include <iostream>
#include <locale>
using namespace std;
                                   
int main()
{
    // 应用环境Locale设置
    wcout.imbue(locale(""));
    wcin.imbue(locale(""));
    wcerr.imbue(locale(""));
                                   
    wcout<<l"万国码c++语言"<<endl;                                        return 0; }< code></l"万国码c++语言"<<endl;></locale></iostream></code>

二、在MFC中使用Unicode的方法

如果是在Visual C++ 7.0以上版本,可以直接在『工程属性』中设置『使用Unicode字符集』还是『使用多字节字符集』。如果是使用Visual Studio 6.0的话,在stdafx.h里设置最方便。
在使用字符串常量时要套上_T("string")宏,使用字符类型TCHAR,字符串指针类型LPCTSTR,这样以保证代码在Unicode编译中的兼容性。要注意一旦使用了Unicode编译模式,程序便不再兼容Windows 95、Windows 98或Windows Me(这些操作系统已经在2006年停止支持,早已过时)。

Visual C++ 6.0中的做法:
<code class="lang-cpp">// 在stdafx.h【最开始处】加入这几句
#undef _MBCS
#define _UNICODE
#define UNICODE
#pragma comment(linker, "/ENTRY:wWinMainCRTStartup") 
                        
// 在使用字符串时要在外边套上宏_T("string")
AfxMessageBox(_T("错误:文件不存在!"));</code>



(完)

[修改于 9年9个月前 - 2015/04/02 20:25:07]

来自:计算机科学 / 软件综合
6
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
acmilan 作者
9年7个月前 IP:四川
769156
在Windows下的wchar_t实现实际上只支持内存保存,输出只能到ANSI字符集,连UTF-8都不支持。要使用UTF-8还得手动转换。
使用UTF-8的方法是调用
<code class="lang-cpp">WideCharToMultiByte(CP_UTF8, 0, wstr, -1, ubuf, sizeof(ubuf), NULL, NULL);
MultiByteToWideChar(CP_UTF8, 0, ustr, -1, wbuf, sizeof(wbuf));</code>
如果需要动态分配内存,把sizeof(ubuf)置零就可以获得需要的字节数了。
<code class="lang-cpp">int nchr = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, ubuf, 0, NULL, NULL);
int nchr = MultiByteToWideChar(CP_UTF8, 0, ustr, -1, wbuf, 0);</code>
UTF-16就比较简单了,直接fread或fwrite即可。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan作者
9年7个月前 IP:四川
769157
在Visual C++中如果需要使用ANSI编译(通常可以避免很多麻烦),可能会发现编译之后界面变得难看了,主要是stdafx.h这里出了问题:
<code class="lang-cpp">// stdafx.h
// 只有Unicode编译才具有Common Controls 6.0外观
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif</code>
这里应该改成
<code class="lang-cpp">// stdafx.h
// 总是具有Common Controls 6.0外观
#if 1
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif</code>
这里是巨硬为了推广Unicode搞的一个小动作,实际上ANSI(MBCS)编译仍然是可以使用Common Controls 6.0外观的。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan作者
9年7个月前 修改于 9年7个月前 IP:四川
769937
关于向文件输出文字所得编码问题:

一、向文本文件中输出宽字符,获得ANSI字符:
<code class="lang-cpp">setlocale(LC_CTYPE, ""); // 获取当前区域设置,默认为C区域设置
FILE * f = fopen("desktop.txt", "r+"); // 文本文件
fwprintf(f, L"我是万国码\n"); // 文件中会得到ANSI字符
fclose(f);</code>

二、向二进制文件中输出宽字符,获得UTF-16LE字符
<code class="lang-cpp">FILE * f = fopen("desktop.txt", "rb+"); // 二进制文件
fwprintf(f, L"\ufeff我是万国码\r\n"); // 文件中获得UTF-16LE字符串,\ufeff是字节序标志
fclose(f);</code>
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan作者
9年7个月前 修改于 9年7个月前 IP:四川
770459
DevCPP和MingW的wchar_t原生不支持中文(Win32使用ANSI存储文本文件,但是GCC却只认UTF-8,所以直接废了)。
原生GCC(Linux、CygWin、WinSUA下的GCC版本)和Visual C++的wchar_t都是支持中文的,但是GCC是4字节,VC是2字节。

另外还要注意,不管是printf、wprintf、sprintf、swprintf、sprintf还是swprintf,处理char*字符串的指示符都是"%s"L"%s",而处理wchar_t*字符串的指示符都是"%ls"L"%ls"
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan作者
9年7个月前 IP:四川
771004
现在已经可以编写纯Unicode程序,而不是ANSI/MBCS程序或兼容字符程序(因为现在早已没多少人使用Windows 98)
微软也在最新版mfc中去除了ANSI/MBCS支持,尽管可以手动安装,但是还是会有警告
可以使用wchar_t、L"string"、wcslen代替TCHAR、_T("string")、_tcslen

不过个人还是习惯编写ANSI/MBCS程序。。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,5年10个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}