UTF-16 字符不一定是 2 个字节宽。它可能是 2 个字节或 4 个字节(在此处阅读)。
您发布的奇怪输出很可能是由于将 wchar_t
s 直接附加到文件,生成字节顺序与右侧相反的 UTF-16 字符,而这些 UTF-16 字符位于UTF-16 范围。
假设您在 Linux 上使用 GCC 的问题标签,您可以通过包含导入字符编码转换 api 来使用该iconv
库。这是一个转换数组<inconv.h>
的示例程序:wchar_t
L'A',L'P',L'P',L'E',L'N',L'D',L'A',L'G',L'E' // "APPENDAGE"
到 UTF-16LE 并将结果附加到文件“tdata.txt”。它对转换后的输出长度限制为 64 个字节。
#include <stdio.h>
#include <stdlib.h>
#include <iconv.h>
#include <assert.h>
#define MAXOUT 64
int main(void)
{
wchar_t appendage [] = {
L'A',L'P',L'P',L'E',L'N',L'D',L'A',L'G',L'E'
};
wchar_t * inp = appendage;
char converted[MAXOUT];
char * outp = converted;
size_t remain_in = sizeof(appendage);
size_t remain_out = MAXOUT;
size_t conversions;
size_t written;
char const *tfile = "../tdata.txt";
// Create the right converter from wchar_t to UTF-16LE
iconv_t iconvdesc = iconv_open("UTF-16LE","WCHAR_T");
if (iconvdesc == (iconv_t) -1) {
perror("error: conversion from wchar_t to UTF-16LE is not available");
exit(EXIT_FAILURE);
}
FILE * fp = fopen(tfile,"a");
if (!fp) {
fprintf(stderr,"error: cannot open \"%s\" for append\n",tfile,stderr);
perror(NULL);
exit(EXIT_FAILURE);
}
// Do the conversion.
conversions =
iconv(iconvdesc, (char **)&inp, &remain_in, (char **)&outp, &remain_out);
if (conversions == (size_t)-1) {
perror("error: iconv() failed");
exit(EXIT_FAILURE);
}
assert(remain_in == 0);
// Write the UTF-16LE
written = fwrite(converted,1,MAXOUT - remain_out,fp);
assert(written == MAXOUT - remain_out);
fclose(fp);
iconv_close(iconvdesc);
exit(EXIT_SUCCESS);
}
对于 GCC,wchar_t
它是 4 个字节宽,因此对于任何 UTF-16 来说都足够宽。对于 Microsoft 的编译器,它是 2 字节宽。
文档<iconv.h>
在这里