在Linux的终端中显示BMPString的内容

在上一篇博文中,介绍了怎样在 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 编译器编译后运行。输出结果例如以下图:

时间: 2025-01-16 13:14:54

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

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

不久前,我们讨论了 Fim,这是一个轻量级的命令行图像查看器应用程序,用于从命令行显示各种类型的图像,如 bmp.gif.jpeg 和 png 等.今天,我偶然发现了一个名为 lsix的类似工具.它类似于类 Unix 系统中的 ls命令,但仅适用于图像.lsix 是一个简单的命令行实用程序,旨在使用 Sixel 图形格式在终端中显示缩略图.对于那些想知道的人来说,Sixel 是六像素six pixels的缩写,是一种位图图形格式.它使用 ImageMagick,因此几乎所有 imagemagic

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

一直苦恼于如何在Windows终端中显示UTF-8字符的问题.比如,在MySQL命令行下,如果数据库的编码是UTF-8,那么,在查询数据库的时候,里面的中文都会变成乱码.今天半无意的搜索了一下,结果发现解决方案非常简单:1. 修改终端的代码页.在终端中输入:chcp 65001 2. 右键点击任务栏上的终端(也可以单击窗口左上角的图标),在快捷菜单中选择属性,在里面选择字体——如 Lucida Console,不要选择“点阵字体”:确定之后,再次测试UTF-8输出,你看到了什么. :)要切换回原

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

如何在浏览器网页中显示word文件内容 把word文件读到byte[]中,再Response.OutputStream.Write(bytes)到客户端去 Page_Load事件中写: //FileStream   fs   =   new   FileStream("c:\\1.doc",   FileMode.Open,   FileAccess.Read);  FileStream fs = new FileStream(Server.MapPath("files\\1

linux字符终端中文显示输入工具zhcon

1,linux使用命令行使用中文,先要安装zhcon,用apt-get install zhcon就可以了. 2,在终端中输入zhcon进入相应模式,ctrl+2切换输入法. 3,修改默认输入法变成五笔   由于输入法切换热键冲突,你只能使用默认的全拼输入法,如果想用五笔,你只要修改配置文件,将想用的五笔输入法行拷贝到全拼输入法前面即可.当然,也可采用加#号屏蔽不需要的,这样不会出错. vi /etc/zhcon.conf    //编辑zhcon配置文件 #type := native | u

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

昨天在配置linux,突然发现root登录的xshell的终端提示符显示的是-bash-4.2# 而不是[email protected]主机名 + 路径的显示方式.搞了半天也不知道为什么出现这种情况.今天终于搞定这个问题,     原因是root在/root下面的几个配置文件丢失,丢失文件如下:   1..bash_profile   2..bashrc  以上这些文件是每个用户都必备的文件.   使用以下命令从主默认文件重新拷贝一份配置信息到/root目录下 -bash-4.2# cp /e

mac终端中显示tree的命令

寻觅了良久终于找到了mac下如何在终端显示tree的命令了,作为从linux下转过来的人,还没适应mac的finder,还是喜欢在命令行下查看文件. 命令: find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g' 然后手动alias一下,在你的.bash_profile或者.zshrc中添加: alias tree="find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'" 搞定

Linux内核启动中显示的logo的修改

1.配置内核 使内核启动时加载logo,在源代码的主目录下make menuconfig Device Drivers  ---> Graphics support  ---> 选上 并 进入 Bootup logo --> 选上 Standard 224-color Linux logo [ * ] 代表选中 [   ]代表未选中 [M]代表编译成模块,使用空格键切换 make重新编译内核,这样启动是就会加载启动logo了. 2.然后就是处理开机图片了. 修改"drivers

linux文本文件查看、显示命令 :cat head tail grep more less nl

linux文本文件查看.显示命令 :cat head tail  grep  more less nl 1.cat 显示文件内容命令. 命令格式:#cat [[选项]] <文件列表> 常用选项: -b,计算所有非空输出行,开始行编号为1. -n,计算所有输出行(包括空行),开始行编号为1. -s,将相连的多个空行用一个空行来代替. -e,在每行的未尾添加$符号,便于确认每一行,因为有些行内容太长了,在显示时会在显示器上以多行表示. 命令使用说明: 例子: 例A: 把 textfile1 的文件

在Linux终端中查看公有IP的方法详解

首先回顾一下一般的查看IP的命令: ifconfigLinux查看IP地址的命令--ifconfigifconfig命令用于查看和更改网络接口的地址和参数 $ifconfig -a  lo0: flags=849 mtu 8232 inet 127.0.0.1 netmask ff000000  hme0: flags=863 mtu 1500 inet 211.101.149.11 netmask ffffff00 broadcast 211.101.149.255 ether 8:0:20: