utuntu unicode打印中文
来源:互联网 发布:c语言编程器 编辑:程序博客网 时间:2024/06/07 05:30
在程序开发中,遇到unicode utf-8编码时,不能向屏幕打印中文字符的情况,经过试验测试可行的方法如下:
程序实例1:
- // 注意,此文档最好采用utf-8编码
- #include <stdio.h>
- #include <wchar.h>
- #include <locale.h>
- int main()
- {
- //此语句重要,在win7 + vs2012和 ubuntu 12.04测试结果一致
- //只要打印wchar_t字符,均加此语句,至少不会出错,此语句最好在程序初始化处
- setlocale(LC_ALL, "");
- // wprintf和printf最好不能同时使用.
- // 如下使用printf同时打印了char字符串和wchar_t字符串
- // 因此只采用printf是比较好的方法
- wchar_t ws[] = L"国家";
- printf("printf content start: %ls\n", ws);
- printf("content end\n");
- return 0;
- }
用上面代码的原因:
1. 从后面我的实验可以看到, 有八种组合方式, 唯独选择这么一种是有原因的.
2. wprintf 和 printf 通用会遇到莫名其妙的问题,
3 . printf可以打印char, 使用格式为小写%s, 也可以打印wchar_t, 使用格式为%ls 或者 大写%S
4. 只要源文件编码为utf-8, 上面的代码就是跨操作系统和编译器平台的, 并且可以统一用一种方式打印char 和 wchar_t 字符串
代码实例2:
#include <iostream>
#include <wchar.h>
using namespace std;
int main()
{
setlocale(LC_ALL,"");
wchar_t ws[]=L"中华人民共和国";
wcout<<ws<<endl;
return 0;
}
注: 需要统一使用wcout,如果前面有使用cout则为错误输出
下面为比较细节的讨论。
关于编码字符集:简单理解为,ascii码表达了美国英文字符,为一字节.
为了统一世界文字编码,出了unicode,如ucs-2,ucs-4,分别为16字节和32字节
因为历史包袱,unicode不可能完全替代以前的编码,所以出了有使用性的UTF-8编码,字节大小不定。
如何快速查看一个文字编码?如“国“字的utf-8编码是什么? 简单方法是新建一文件,记事本输入“国”, 记事本另存为,选择文件编码。 然后使用如下方式打开此文件,1:使用winhex软件 2. 使用notep++,选中文字”国“,点击菜单插件->converter->ascii to hex, 3, 其它.... (在线的就算了,我看了百度两个排名前两位的网站根本不是转的UTF-8, 而是转成了ucs-2,虽然其号称是转换成UTF-8)
如下表格是使用wchar_t的总结,其中编码格式设置是通过notepad++的格式菜单进行的,如下表格的测试代码后面会贴出来。
表格解释:
1.采用ansi编码方式,在ubuntu下会出错,另外通过g++ -Wall -finput-charset=ISO-8859-1 test.cpp 方式可以指定输入文件格式,但是这样很麻烦,因为首先要知道文件的格式是什么,在ubuntu下 通过file test.cpp 命令可以查到,我把ISO-8859-1到ISO-8859-16都试了,文件编码格式ANSI(即ISO8859-XX)且文件中有L"国家" 类似字符,编译不会通过,或者通过-finput-charset=xxx指定文件格式编译通过后输出也不对,故太麻烦。
2.在windows下和ubuntu下都通过的方式是文件编码采用UTF-8。
3.printf和wprintf不能混用,即一个程序中使用了printf, 就不使用wprintf,反之也是,既然printf输出char 和 wchar_t字符都可以,所以统一使用printf是最佳选择。
当然使用printf打印wchar_t时格式不一样,是%ls 或大写的%S, 例如: printf("wide char: %ls\n", ws);
4. 一旦要打印中文字符,在程序初始化时加一句setlocale(LC_ALL, ""); 否则打印中文会出错。
5. windows 对 字符串的内部编码比较统一,char的编码都成ANSI,如 char s[] = "国家", s里存的是”国家”的ANSI编码
wchar_t的编码都成UCS-2,如 wchar_t ws[] = L"国家", s里存的是”国家”的UCS-2编码
UBUNTU 对字符串的处理不是很统一,char 字符串的编码是随着文件编码格式有所变化,如文件为ansi,则ubuntu也为ansi,文件为UTF-8, 则char s[] = "国家" 里的也是 UTF-8编码。
wchar_t 则默认采用ucs-4编码。
总结:源代码文件编码用UTF-8, 打印采用printf是跨平台(操作系统,编译器), 跨char和wchar_t的最佳解决方案之一,另外不能忘了 setlocale(LC_ALL, "");
说的再多,不如自己测试下,如下为测试代码,一共有5种case,每次注释掉其他case,留要测试的case,并按照case注释处更改文件编码方式便可, 更改编码方式采用notepad++最方便了.
#include <stdio.h>#include <string.h>
#include <stddef.h>
#include <wchar.h>
#include <locale.h>
// 测试运行环境:
// ubuntu 12.04 + g++ 4.6.3(或gcc,改文件后缀就行)
// windows 7 + vs2012
// 说明,在注释中说的编码E59BBD,是按照打印结果从低字节到高字节排练,并不一定和实际
// 的编码大小端一致。
int main()
{
//此语句重要,在win7 + vs2012和 ubuntu 12.04测试结果一致,只要打印wchar_t字符,均加此语句,否则出错。
setlocale(LC_ALL, "");
/****************** case 1 **********************************/
// 文件utf-8编码, 字符串不加L
// ubuntu : ws是utf-8编码: 如"国":E59BBD; 打印结果:国家
// windows: ws是ansi编码: 如"国":b9fa; 打印结果: 国家
/* char ws[] = "国家";
char *p = (char *)ws;
int i = 0;
printf("sizeof(ws) is %d\n", sizeof(ws));
for (; i < sizeof(ws); i++){
printf("byte: %x\n", p[i]);
}
printf("content start\n");
printf("%s\n", ws);
printf("content end\n"); */
/****************** case 2 **********************************/
// 2: 文件ansi编码, 字符串不加L
// ubuntu : ws是ansi编码,如"国":b9fa; 打印结果:无,出错
// windows: ws是ansi编码: 如"国":b9fa; 打印结果: 国家
/* char ws[] = "国家";
char *p = (char *)ws;
int i = 0;
//setlocale(LC_ALL, "zh_CN.UTF-8");
printf("sizeof(ws) is %d\n", sizeof(ws));
for (; i < sizeof(ws); i++){
printf("byte: %x\n", p[i]);
}
printf("content start: %s\n", ws);
printf("content end\n"); */
/****************** case 3 **********************************/
// 3: 文件utf-8编码, 字符串加L, 必须采用wchar_t, 用char编译器报错, 用wprintf打印
// ubuntu : ws是ucs-4编码,如"国":0x000056fd; 打印结果:国家
// windows: ws是ucs-2编码: 如"国":0x56fd; 打印结果: 国家
/* wchar_t ws[] = L"国家";
char *p = (char *)ws;
int i = 0;
wprintf(L"sizeof(ws) is %d\n", sizeof(ws));
for (; i < sizeof(ws); i++){
wprintf(L"byte: %x\n", p[i]);
}
wprintf(L"wprintf content start:\n"); //必须用wprintf, 且wprintf和printf不能同时使用.
wprintf(L"%ls\n", ws);
wprintf(L"content end\n"); */
/****************** case 4 **********************************/
// 4: 文件utf-8编码, 字符串加L, 必须采用wchar_t, 用char编译器报错, 用printf打印
// ubuntu : ws是ucs-4编码,如"国":0x000056fd; 打印结果:国家
// windows: ws是ucs-2编码: 如"国":0x56fd; 打印结果: 国家
wchar_t ws[] = L"国家";
char *p = (char *)ws;
int i = 0;
printf("sizeof(ws) is %d\n", sizeof(ws));
for (; i < sizeof(ws); i++){
printf("byte: %x\n", p[i]);
}
printf("printf content start:\n"); //wprintf和printf不能同时使用.
printf("%ls\n", ws);
printf("content end\n");
/****************** case 5 **********************************/
// 5: 文件ansi编码, 字符串加L, 必须采用wchar_t, 用char编译器报错
// ubuntu : 编译不通过
// windows: ws是ucs-2编码: 如"国":0x56fd; 打印结果: 国家
/* wchar_t ws[] = L"国家"; // 文件ansi编码,ws是unicode编码: 如国:56fd
char *p = (char *)ws;
int i = 0;
wprintf(L"sizeof(ws) is %d\n", sizeof(ws));
for (; i < sizeof(ws); i++){
wprintf(L"byte: %x\n", p[i]);
}
wprintf(L"wprintf content start:\n"); //必须用wprintf, 且wprintf和printf不能同时使用.
wprintf(L"%ls\n", ws);
wprintf(L"content end\n"); */
while(1); //方便看结果
return 0;
}
其他相关参考资料
https://www.polarxiong.com/archives/ubuntu%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%AD%E8%AE%BE%E7%BD%AElocale%E4%B8%BA%E4%B8%AD%E6%96%87%E4%BB%8D%E7%84%B6%E6%97%A0%E6%95%88%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.html
http://www.cnblogs.com/yg_zhang/p/4331498.html
http://blog.csdn.net/magicxiaoz/article/details/4347414
- utuntu unicode打印中文
- 将unicode转换成中文打印输出
- Xcode 控制台打印中文被unicode编码
- iOS 打印Unicode码转中文的解决办法
- Python 打印list是显示unicode,转化成中文
- 打印Unicode 字符
- python 打印unicode字符串
- 打印中文的问题(470系统未装Unicode和多语言支持)
- python写的crond后台任务打印包含中文字符的unicode 字符串,出现异常?
- IOS中 打印字典、数组时 直接显示中文(而不是显示Unicode字符)
- VS2015,UNICODE字符集下printf,cout打印CString,与TRACE输出中文调试
- Android 解决使用Log打印日志的时候中文是乱码(unicode)
- Python最简单的解决列表中只打印UNICODE而不是中文字符的方法
- 打印中文
- python,unicode转换中文,中文转换unicode
- C#中文转Unicode、Unicode转中文
- 打印、注释、打印中文
- unicode处理中文
- 资源 | 8张思维导图帮你梳理深度学习&机器学习多个知识点
- 探索 | 神经网络到底是如何思考的?MIT精英们做了这么一个实验室来搞清楚
- 如何优雅地用TensorFlow预测时间序列:TFTS库详细教程
- 课程 | 想成为高薪、抢手又能改变世界的机器学习工程师?
- 经验 | 如何高效学Python?
- utuntu unicode打印中文
- 挑战程序设计竞赛 算法和数据结构 第12章 图
- STL容器Set和Multiset
- Pandas学习笔记:pandas基础
- LeetCode-ZigZag Conversion
- android-studio安装过程详解
- 开源地图MapBox自定义(二):基本概念
- Android文件上传带参数
- 重磅 | 周志华最新论文:首个基于决策树集成的自动编码器,表现优于DNN