版权声明:本文章为博主原创,转载请注明出处。保留所有权利。

Contents
  1. 1. unicode编码的文本文件
  2. 2. 用C语言读取unicode码
  3. 3. 宽字符转换为多字节字符

 最近的一个作业,目的是从一个Unicode编码的文本文件中读取中文字符的内码并显示在控制台中。

  • unicode编码的文本文件

 很简单,windows自带的记事本就提供了在保存时设置编码的功能,设置一下就可以了
保存为unicode编码

 列表中还有一个unicode-bigendian,这个的意思是大端模式下的unicode,因为unicode是两个字节的数据代表一个字符,所以在大端模式下和小端模式下的存储方式是不同的。

 小端模式即低位字节存储在低地址段,高位字节存储在高地址段。大端模式则正好相反。所以如果在大端机器上读取小端模式的unicode或者在小端机器上读取大端模式的unicode的话,需要将读出来的两个字节调换一下顺序。如果想深入了解一下大端模式和小端模式的话,可以参考这篇博文:详解大端模式和小端模式,这篇文章里面也提供了判断一台机器是大端机还是小端机的代码。

  • 用C语言读取unicode码

 前面已经说过,unicode编码方式是用两个字节的编码来表示一个字符,所以读文件的时候一次读2字节的数据就可以了。但是要注意一点,unicode编码的文本文件会的开头两个字节是0xFEFF,这个东西的学名叫做“ZERO WIDTH NO-BREAK SPACE”,并不代表某个字符,而是一种格式上的形式规定,读取字符的时候记得要判断一下。

1
2
3
4
5
6
7
8
9
10
11
FILE* file = fopen("unicode2.txt","rb");//打开文件
unsigned short unicode;//读取unicode编码
if (file != NULL) {
while (true) {
fread(&unicode, 2, 1, file);
if (feof(file))break;
printf("%x\n", unicode);
if (unicode != 0xfeff) {
//TODO
}
}

 通过上面的代码,就可以从文件中读出每个字符对应的unicode编码了。读出来的unicode编码存放在一个unsigned short变量中,这样是没法作为字符串来输出的。

  • 宽字符转换为多字节字符

 我们需要调用一些函数将unicode宽字符转换为多字节字符。其中之一就是wcstombs()函数,这个函数由C语言本身提供,用于转换wchar_t和char[](与之相反的是mbstowcs),所以在windows和linux下都可以使用。

 wchar_t类型即是宽字符,这里说明一下,在纯C中,除了一些平台上的例外,wchar_t类型只是unsigned short类型的一个typedef别名,也就是说二者是等价的;而在C++中,wchar_t则像int/char这些类型一样是内建类型。

 将下面的代码放在上面的//TODO处,进行转换:

1
2
3
4
5
6
//unicode = (unicode << 8) | (unicode >> 8);//调换前后两个字节的顺序
char str[3] = {0};
str[2] = '\0';//\0作为字符串结尾
setlocale(LC_ALL, "");//配置地域的信息,设置当前程序使用的本地化信息。
wcstombs(str, (wchar_t*)(&unicode), 2);//将unicode宽字符转换成多字节字符
printf("%s\n", str);

 经过上面的代码,就可以通过读unicode编码显示中文字符了:

显示中文字符

 最后附上完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <Windows.h>
#include <locale>
using namespace std;
int main() {
FILE* file = fopen("unicode2.txt","rb");//打开文件
unsigned short unicode;//读取unicode编码
if (file != NULL) {
while (true) {
fread(&unicode, 2, 1, file);
if (feof(file))break;
//printf("%x\n", unicode);
if (unicode != 0xfeff) {
//unicode = (unicode << 8) | (unicode >> 8);//调换前后两个字节的顺序
char str[3] = {0};
str[2] = '\0';//\0作为字符串结尾
setlocale(LC_ALL, "");//配置地域的信息,设置当前程序使用的本地化信息。
wcstombs(str, (wchar_t*)(&unicode), 2);//将unicode宽字符转换成多字节字符
printf("%s", str);
}
}
printf("\n");
fclose(file);
file = NULL;
}
return 0;
}

打赏

取消
扫码支持

你的支持是对我最好的鼓励

Contents
  1. 1. unicode编码的文本文件
  2. 2. 用C语言读取unicode码
  3. 3. 宽字符转换为多字节字符