C++使用WideCharToMultiByte函数生成UTF-8编码文件的方法

所属分类: 软件编程 / C 语言 阅读数: 68
收藏 0 赞 0 分享

WideCharToMultiByte函数映射一个unicode字符串到一个多字节字符串。

函数原型:

int WideCharToMultiByte

  • UINT CodePage, //指定执行转换的代码页
  • DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符
  • LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区
  • int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数
  • LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区
  • int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值
  • LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符
  • LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE

参数:
CodePage:指定执行转换的代码页,这个参数可以为系统已安装或有效的任何代码页所给定的值。你也可以指定其为下面的任意一值:

  • CP_ACP:ANSI代码页;CP_MACCP:Macintosh代码页;CP_OEMCP:OEM代码页;
  • CP_SYMBOL:符号代码页(42);CP_THREAD_ACP:当前线程ANSI代码页;
  • CP_UTF7:使用UTF-7转换;CP_UTF8:使用UTF-8转换。

相关变量

  • lpWideCharStr:指向将被转换的unicode字符串。
  • cchWideChar:指定由参数lpWideCharStr指向的缓冲区的字符个数。如果这个值为-1,字符串将被设定为以NULL为结束符的字符串,并且自动计算长度。
  • lpMultiByteStr:指向接收被转换字符串的缓冲区。
  • cchMultiByte:指定由参数lpMultiByteStr指向的缓冲区最大值(用字节来计量)。若此值为零,函数返回lpMultiByteStr指向的目标缓冲区所必需的字节数,在这种情况下,lpMultiByteStr参数通常为NULL。
  • lpDefaultChar和pfUsedDefaultChar:只有当WideCharToMultiByte函数遇到一个宽字节字符,而该字符在uCodePage参数标识的代码页中并没有它的表示法时,WideCharToMultiByte函数才使用这两个参数。如果宽字节字符不能被转换,该函数便使用lpDefaultChar参数指向的字符。如果该参数是NULL(这是大多数情况下的参数值),那么该函数使用系统的默认字符。该默认字符通常是个问号。这对于文件名来说是危险的,因为问号是个通配符。pfUsedDefaultChar参数指向一个布尔变量,如果Unicode字符串中至少有一个字符不能转换成等价多字节字符,那么函数就将该变量置为TRUE。如果所有字符均被成功地转换,那么该函数就将该变量置为FALSE。当函数返回以便检查宽字节字符串是否被成功地转换后,可以测试该变量。
  • 返回值:如果函数运行成功,并且cchMultiByte不为零,返回值是由 lpMultiByteStr指向的缓冲区中写入的字节数;如果函数运行成功,并且cchMultiByte为零,返回值是接收到待转换字符串的缓冲区所必需的字节数。如果函数运行失败,返回值为零。若想获得更多错误信息,请调用GetLastError函数。它可以返回下面所列错误代码:
  • ERROR_INSUFFICIENT_BJFFER;ERROR_INVALID_FLAGS;
  • ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION。
  • 注意:指针lpMultiByteStr和lpWideCharStr必须不一样。如果一样,函数将失败,GetLastError将返回ERROR_INVALID_PARAMETER的值。
  • Windows CE:不支持参数CodePage中的CP_UTF7和CP_UTF8的值,以及参数dwFlags中的WC_NO_BEST_FIT_CHARS值。

生成utf-8编码的文件
步骤如下:
1. 首先要写一个BOM头。UTF-8文件一般是要这个头的,当然也可以没有。
2. 将要生成的字符先使用宽字符格式生成,然后调用WideCharToMultiByte转为utf-8编码,写入文件。

例子如下:

FILE * pFile = fopen("d://a.txt", "w"); 
  char szBOM[4] = {(char)0xEF, (char)0xBB, (char)0xBF, 0}; 
  fprintf(pFile, "%s", szBOM); 
   
  wchar_t chNum[11] = L"零壹贰叁肆伍陆柒捌玖"; 
  wchar_t chNum2[10] = L"亿千百拾万千百拾个"; 
  char sz[10] = "112304823"; 
   
  wchar_t result[32] = L""; 
   
  int offset = 0; 
  for(int i = 0; i < strlen(sz); ++ i) 
  { 
    char c = sz[i]; 
     
    wchar_t w1 = chNum[ c - '0']; 
    wchar_t w2 = chNum2[i]; 
    swprintf(result + offset, L"%c%c", w1, w2); 
    offset += 2; 
  } 
  char szChar[64] = ""; 
  ::WideCharToMultiByte(CP_UTF8, 0, result, wcslen(result), szChar, 64, 0, 0); 
  fprintf(pFile, "%s", szChar); 
  fclose(pFile); 

注意的是,当使用wchar_t而不再是char时,所有的字符串操作函数都需要时w系列的,例如wcslen、swprintf

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多