在上一篇博文中,介绍了怎样在 Windows 的控制台界面下输出 BMPString 的内容,可是那里的方法在 Linux 下不适用。假设将那里的演示样例代码放到 Linux 下运行。输出的结果为乱码。产生乱码的原因在于 wchar_t 类型的变量在 Windows 下和 Linux 下的字节长度不同。

下面 C 程序在 Windows 和 Linux 下都可以运行:

#include <stdio.h>
#include <wchar.h>
#if defined(_WIN32) || defined(_WIN64)
#include <stdlib.h>
#endif
int main(void)
{
printf("wide character (wchar_t type) length is %d bytes.\n", sizeof(wchar_t));
#if defined(_WIN32) || defined(_WIN64)
system("pause");
#endif
return 0;
}

输出结果是不同的。

在 64 位 Windows 下。用微软的编译器将其分别编译成 32 位和 64 位可运行程序,输出结果证明 wchar_t 类型变量长度为 2 字节。

在 64 位 Linux 下。用 64 位的 GCC 编译后运行,输出结果证明 wchar_t 类型变量长度为 4 字节。

在 Windows 下处理 BMPString 时,比方对于字符“中”,相应的 UTF-16 编码是0x4E, 0x2D,我们处理的方法是将其由 big-endian 顺序转换为 little-endian 顺序,再用 wprintf() 函数输出。

在 Linux 下处理 BMPString 时。比方对于字符“中”。相应的 UTF-16 编码是0x4E, 0x2D,我们处理的方法是将其由 2 字节长扩展到 4 字节长,扩展时新加入的两个字节的值为 0。即变为 0x0, 0x0, 0x4E, 0x2D。再由 big-endian 顺序转换为 little-endian 顺序,即编码变成 0x2D, 0x4E, 0x0, 0x0。再用 wprintf() 函数输出。

所以在 Linux 下要显示 BMPString,一般方法是先将 UTF-16 big-endian 方式的字符编码扩展为 UTF-32 big-endian 方式的字符编码,扩展方法是在前面加上两个字节的 0。再将UTF-32 big-endian 方式的字符编码变为 UTF-32 little-endian 方式的字符编码。(也可先将 UTF-16 big-endian 方式的字符编码转换为 little-endian 顺序,再给后面加上两个字节的 0。效果是一样的。)

以下给出一个演示样例程序:

/**************************************************
* Author: HAN Wei
* Author's blog: http://blog.csdn.net/henter/
* Date: Oct 31th, 2014
* Description: demonstrate how to print BMPString
on Linux console
**************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <wchar.h> /**************************************************
*函数名称:PrintBMPStringOnLinux
*功能: 在 Linux 终端下输出 BMPString
*參数:
BMPString [in]
BMPString_len [in] BMPString 的长度,以字节为单位
*返回值:
0 成功
-1 失败
**************************************************/ int PrintBMPStringOnLinux(unsigned char *BMPString, unsigned int BMPString_len)
{
unsigned char *buffer;
unsigned int buffer_len, i;
unsigned char *p, *q; buffer_len = BMPString_len * 2 + 4; /* 缓冲区大小为 BMPString 的字节长度的两倍
再加上四个字节。这四个字节用来存放字符串
结束符 \0(其类型为 wchar_t ),其相应
编码是 0x0, 0x0, 0x0, 0x0 */ if ( !(buffer = (unsigned char *)malloc(buffer_len)) )
{
#ifdef _DEBUG
printf("malloc() function failed!\n");
#endif
return (-1);
} memset(buffer, 0, buffer_len);
p = buffer;
q = BMPString;
for (i=0; i < (int)BMPString_len/2; i++)
{
*p = *(q+1);
*(p+1) = *q;
p += 4;
q += 2;
} setlocale(LC_ALL, "zh_CN.utf8");
wprintf(L"BMPString: %ls\n", (wchar_t *)buffer);
free(buffer);
return 0;
} int main(void)
{
int error_code;
unsigned char BMPString_data1[]={0x4e, 0x2d, 0x56, 0xfd}; /* 中文字符串"中国"相应的 Unicode 编码 */
unsigned char BMPString_data2[]={0x0, 0x55, 0x0, 0x73, 0x0, 0x65, 0x0, 0x72}; /* 英文字符串"User"相应的 Unicode 编码 */
char str[]={0x2d, 0x4e, 0x0, 0x0, 0xfd, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; if ( error_code = PrintBMPStringOnLinux(BMPString_data1, sizeof(BMPString_data1)) )
{
printf("Print BMPstring on Windows console failed!\n");
return (-1);
} if ( error_code = PrintBMPStringOnLinux(BMPString_data2, sizeof(BMPString_data2)) )
{
printf("Print BMPstring on Windows console failed!\n");
return (-1);
} /* 以下给出了说明 unicode 编码的字符在 Linux 中是怎样存放的一个样例,
从显示结果能够看出:对于每个用 wchar_t 类型保存的 UTF-16 字符,
长度为 4 字节。以 little-endian 顺序存放 */
printf("\n");
setlocale(LC_ALL, "zh_CN.utf8");
wprintf(L"%ls\n", (wchar_t *)str); return 0;
}

该程序在 64 位 CentOS 下,用 64位 GCC 编译器编译后运行。输出结果例如以下图:

在Linux的终端中显示BMPString的内容的更多相关文章

  1. 在Windows的控制台和Linux的终端中显示加载进度

    Windows中 #include <stdio.h> #include <windows.h> int main() { ;//任务完成总量 int i; ; i < ...

  2. 使用 Sixel 图形格式在终端中显示缩略图

    不久前,我们讨论了 Fim,这是一个轻量级的命令行图像查看器应用程序,用于从命令行显示各种类型的图像,如 bmp.gif.jpeg 和 png 等.今天,我偶然发现了一个名为 lsix的类似工具.它类 ...

  3. 【转载】在Windows终端中显示UTF-8字符

    一直苦恼于如何在Windows终端中显示UTF-8字符的问题.比如,在MySQL命令行下,如果数据库的编码是UTF-8,那么,在查询数据库的时候,里面的中文都会变成乱码.今天半无意的搜索了一下,结果发 ...

  4. repeter 控制一行中显示几条内容

    repeter  控制一行中显示几条内容 <asp:Repeater ID="Repeater1" runat="server" DataSourceID ...

  5. 如何在浏览器网页中显示word文件内容

    如何在浏览器网页中显示word文件内容 把word文件读到byte[]中,再Response.OutputStream.Write(bytes)到客户端去 Page_Load事件中写: //FileS ...

  6. linux 命令终端提示符显示-bash-4.1#解决方法

    昨天在配置linux,突然发现root登录的CRT的终端提示符显示的是-bash-4.1# 而不是root@主机名 + 路径的显示方式.搞了半天也不知道为什么出现这种情况.今天终于搞定这个问题, 原因 ...

  7. linux 命令终端提示符显示-bash-4.2#解决方法

    原地址:http://blog.csdn.net/liulihui1988/article/details/52796395 终端提示符显示的是-bash-4.2# 而不是root@主机名 + 路径的 ...

  8. linux在终端中按下键盘立马反应

    想在终端中做个小应用,按下上下左右键能立刻作出反应. 测试程序见下: 1 #include <stdio.h> 2 #include <unistd.h> 3 #include ...

  9. 如何让同一个字段在不同的view中显示不同的内容

    many2one 字段默认显示 对象的name字段, 但也可以定义name_get方法显示不同的内容 如res.partner 对象可以根据 context 内容是否显示 客户的地址,职位,email ...

随机推荐

  1. 题解 P3978 【[TJOI2015]概率论】

    这道题...好像是第一道我自己切出来的黑题... 先说一句,牛顿二项式蒟蒻并不会,可以说是直接套结论. 求诸位老爷轻喷. 这道题用卡特兰数搞. 卡特兰数这玩意从普及组初赛一路考到省选,十分有用. 如果 ...

  2. Android蓝牙串口程序开发

    本文主要介绍了针对android的蓝牙串口上位机开发. 程序下载地址:点击打开链接 一.帧定义 androidclient依照一定的数据帧格式通过蓝牙串口发送数据到连接到MCU的蓝牙从机.MCU接收到 ...

  3. iOS开发UI调试神器----Reveal

    做iOS的开发,UI是非常非常重要的一环.调试时我们一般用模拟器,提交前用真机做測试.用模拟器来调试UI效果尽管快捷方便,但有时仍然希望有更强大的工具来帮助分析UI,尤其是专注在UI的效果调试时.近期 ...

  4. spark集群体系结构

  5. MyBatis数据持久化(七)多表连接查询

    本节继续以多表连接查询的案例介绍使用resultMap的好处,对于两张以上的表进行关联查询,当我们有选择的从不同表查询所需字段时,使用resultMap是相当方便的.例如我们有两张表,分别为用户表Us ...

  6. 1806最大数 string和sort函数用法

    1.C++自带sort函数用法 sort函数有三个参数: (1)第一个是要排序的数组的起始地址 (2)第二个是结束的地址(最后一位要排序的地址) (3)第三个参数是排序的方法,可以是从大到小也可是从小 ...

  7. SQL 的stuff函数

    1.作用 删除指定长度的字符,并在指定的起点处插入另一组字符. 2.语法 STUFF ( character_expression , start , length ,character_expres ...

  8. 利用SQL索引提高查询速度

    1.合理使用索引 索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率.现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构. 索引的使用要恰到好处,其使用原则如下: 在经常进行连接 ...

  9. rem 使用

    html{ font-size:12px; } .btn { width: 6rem; height: 3rem; line-height: 3rem; font-size: 2rem; displa ...

  10. centos下nginx配置

    转自  http://www.linuxidc.com/Linux/2016-09/134907.htm 安装所需环境 Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Wi ...