程序国际化的编码问题
来源:互联网 发布:手机桌面清理软件 编辑:程序博客网 时间:2024/05/16 06:09
场景: 有一个程序需要国际化, 需要支持多国语言(中文, 英文, 日文, 阿拉伯文等等)
2. 我知道有一个叫 GetText的, 支持国际化的工具(搜索poEdit或者po文件可以了解). 我也使用过, 很好用, 很方便.
3. 自己还是有一点折腾吧, 想自己实现.(可能会给自己带来风险, 如果万一实现不了.)
背景: Win7简体中文系统, 使用VC构建的工程.
相信很多人为选择哪一项而纠结, 我也是一样, 所以把心一横, 自己一律使用Multi-Byte Character Set.
3). 但是执行下面语句可以正确显示阿拉伯文
std::wstring str = L" كيف حالك؟ "; // 阿拉伯文
::SetWindowTextW(GetDlgItem(IDC_STATIC_SHOW)->m_hWnd, str.c_str());
3). 执行下面语句也可以正确显示阿拉伯文
std::wstring str = L" كيف حالك؟ ";// 阿拉伯文
::SetWindowTextW(GetDlgItem(IDC_STATIC_SHOW)->m_hWnd, str.c_str());
4). 但是执行下面语句就不行了.
std::wstring str = " كيف حالك؟ ";// 阿拉伯文(其实在这一句已经是不行的了)
::SetWindowTextA(GetDlgItem(IDC_STATIC_SHOW)->m_hWnd, str.c_str());
3). 或者说阿拉伯文只有Unicode编码, 没有多字节编码.
4). Multi-Byte Character Set下, 都输入不了阿拉伯文, 个人理解就是编码的原因吧. 所以建议以后还是使用Use Unicode Character Set.
现在增加阿拉伯文, 问题就是阿拉伯文用Unicode编码形式, 有类似0x00XX的编码, 在多字节形式的字符中, 一遇上0x00就被截断了.
3). 例如std::wofstream输出std::wstring(内容是中英日文)到文件, 最终在文件上是多字节形式的, 内容是正确的.(内部自动的正确转换了).
4). 例如std::wofstream输出std::wstring(内容是阿拉伯文)到文件, 最终在文件上是多字节形式的, 但内容是错误的.(内部自动转换了, 但转换错误的).
5). 或者可以使用std::locale::global(std::locale(""))设置转换的编码吧, 但我没有尝试.
1). 方法1. 使用std::locale::global(std::locale("")): 这种方法不够通用. 例如我同时要转换中文, 阿拉伯文, 就需要频繁的切换. 容易犯错.
2). 方法2. xml文件保存为Unicode形式: 这是一个终极解决方法.(对于我来说, 需要花时间实现(我想用C/C++的标准函数实现), 而且我之前的xml数据怎么兼容?).
3). 方法3. 手动对所有Unicode编码转换成统一的多字节编码(例如可视十六进制), 再存储到多字节形式的xml文件中.(保存前需要转换, 加载后需要逆转换, 增加了运行时间.)(这方法对我来说是最兼容的.)
3). std::iofstream/std::wiofstream最终处理的还是多字节, 而且转换与本地环境相关, 没有一个通用性.
4). 可以考虑可视十六进制来存储(还是多字节文件), 我喜欢.
实现的大致思路:
1. 把语言信息保存在对应的xml文件中, 用户选择语言时, 加载对应的xml文件显示.2. 我知道有一个叫 GetText的, 支持国际化的工具(搜索poEdit或者po文件可以了解). 我也使用过, 很好用, 很方便.
3. 自己还是有一点折腾吧, 想自己实现.(可能会给自己带来风险, 如果万一实现不了.)
背景: Win7简体中文系统, 使用VC构建的工程.
遇到的问题:
一. VC的Character Set问题.
VC工程有一个Character Set选项, 可以选择Not Set / Use Unicode Character Set / Use Multi-Byte Character Set.相信很多人为选择哪一项而纠结, 我也是一样, 所以把心一横, 自己一律使用Multi-Byte Character Set.
1.1 Multi-Byte Character Set下:
1). 在CEdit上输入/拷贝/粘贴中文, 英文, 日文都没有问题.
2). 在CEdit上输入/拷贝/粘贴阿拉伯文不行, 全部变成"?????".3). 但是执行下面语句可以正确显示阿拉伯文
std::wstring str = L" كيف حالك؟ "; // 阿拉伯文
::SetWindowTextW(GetDlgItem(IDC_STATIC_SHOW)->m_hWnd, str.c_str());
1.2 Use Unicode Character Set下:
1). 在CEdit上输入/拷贝/粘贴中文, 英文, 日文都没有问题.
2). 在CEdit上输入/拷贝/粘贴阿拉伯文也没有问题.3). 执行下面语句也可以正确显示阿拉伯文
std::wstring str = L" كيف حالك؟ ";// 阿拉伯文
::SetWindowTextW(GetDlgItem(IDC_STATIC_SHOW)->m_hWnd, str.c_str());
4). 但是执行下面语句就不行了.
std::wstring str = " كيف حالك؟ ";// 阿拉伯文(其实在这一句已经是不行的了)
::SetWindowTextA(GetDlgItem(IDC_STATIC_SHOW)->m_hWnd, str.c_str());
1.3 说明
1). 查了这一句阿拉伯文的值, 发现有一个值是0x002E. 所以很明显, 是Unicode编码, 需要使用std::wstring存储.(暂时这么理解)
2). 在中文/日文中, 并没有类似0x00XX的编码, 所以中文也可以使用std::string存储.(暂时这么理解)3). 或者说阿拉伯文只有Unicode编码, 没有多字节编码.
4). Multi-Byte Character Set下, 都输入不了阿拉伯文, 个人理解就是编码的原因吧. 所以建议以后还是使用Use Unicode Character Set.
二. 保存为xml文件问题.
我一直使用自己写的xml文件操作类, 使用std::iofstream进行xml文件的读写. 很明显, 这些都是以多字节的形式处理的.xml文件中保存/加载中英日文都没有问题.现在增加阿拉伯文, 问题就是阿拉伯文用Unicode编码形式, 有类似0x00XX的编码, 在多字节形式的字符中, 一遇上0x00就被截断了.
2.1 std::wofstream 与 std::ofstream
1). 我第一时间想到std::wofstream,但是std::wofstream只是文件名支持Unicode, 输入内容最终还是多字节编码的.
2). std::wofstream在处理 unicode字符时, 必须进行内部编码转换(Unicode -> 多字节); 但是怎么转换的呢? 明显是与你本地系统编码或者与std::locale::global(std::locale(""))设置的有关系.3). 例如std::wofstream输出std::wstring(内容是中英日文)到文件, 最终在文件上是多字节形式的, 内容是正确的.(内部自动的正确转换了).
4). 例如std::wofstream输出std::wstring(内容是阿拉伯文)到文件, 最终在文件上是多字节形式的, 但内容是错误的.(内部自动转换了, 但转换错误的).
5). 或者可以使用std::locale::global(std::locale(""))设置转换的编码吧, 但我没有尝试.
2.2 解决方法
现在的矛盾在于: xml文件是多字节形式存储, 但是又要存储Unicode编码数据. 思路无非就是Unicode编码转多字节后再保存到xml文件中. 或者xml文件使用Unicode的形式.
1). 方法1. 使用std::locale::global(std::locale("")): 这种方法不够通用. 例如我同时要转换中文, 阿拉伯文, 就需要频繁的切换. 容易犯错.
2). 方法2. xml文件保存为Unicode形式: 这是一个终极解决方法.(对于我来说, 需要花时间实现(我想用C/C++的标准函数实现), 而且我之前的xml数据怎么兼容?).
3). 方法3. 手动对所有Unicode编码转换成统一的多字节编码(例如可视十六进制), 再存储到多字节形式的xml文件中.(保存前需要转换, 加载后需要逆转换, 增加了运行时间.)(这方法对我来说是最兼容的.)
三. 小结
1). VC工程需要选择Use Unicode Character Set, 保证Unicode编码的语言可以输入/输出.
2). Unicode编码的文本不能保存到多字节的文本中, 要保存到Unicode编码的文件中, 不能简单的使用std::iofstream/std::wiofstream来处理.3). std::iofstream/std::wiofstream最终处理的还是多字节, 而且转换与本地环境相关, 没有一个通用性.
4). 可以考虑可视十六进制来存储(还是多字节文件), 我喜欢.
0 0
- 程序国际化的编码问题
- Struts的properties国际化文件的编码问题及解决方案
- struts 国际化 中文编码问题
- Struts国际化中文编码问题
- Java程序的国际化
- php程序的国际化
- PySide程序的国际化
- Java程序的国际化
- Android的硬编码国际化
- Android的硬编码国际化
- 一个解决VC++程序国际化的类,解决乱码问题
- 一个解决VC++程序国际化的类,解决乱码问题
- 关于编写QT国际化程序中需要注意的问题
- struts的国际化问题
- Struts 国际化的问题
- Java的国际化问题
- flex国际化的问题
- struts的国际化问题
- 图解MBR分区无损转换GPT分区+UEFI引导安装WIN8.1
- POJ 1741 Tree (树上点分治)(楼教主男人八题之一)
- 【操作系统】文件管理
- Maven详解之仓库------本地仓库、远程仓库
- Android之activity总结
- 程序国际化的编码问题
- matlab纵波动画
- 贝塞尔曲线 (Bézier curve) 理论及绘制方法
- mysql查询优化(一)
- 剑指offer 例题
- J2SE总结
- D题 Codeforces 325B Stadium And Games
- 网络编程API-下 (I/O复用函数)
- HTML 标签 <h1> 到 <h6>