【问题标题】:Append text to an existing UTF16LE file将文本附加到现有的 UTF16LE 文件
【发布时间】:2013-05-01 04:23:03
【问题描述】:

如何使用 UTF16LE 编码写入现有文件?我已经使用了fopen(file, "a");,但生成的文件会是这样的:

<?xml version="1.0" encoding="UTF-16" standalone="yes"?> 㰼㱤㱯㱣㰾㰊㰼㱰㱡㱧㱥㰠㱮㱡㱭㱥㰽㰢㱎㱏㱒㱍㱁㱌㰢㰾㰊㰼㱦㱩㱥㱬㱤㰠㱮㱡㱭㱥㰽㰢㱉㱤㱥㱮㱴㱩㱦㱩㱣㱡㱴㱩㱯㱮㸢㱔㱃㰳㰶㰰㰴㰰㰱㰭㰭㰭㰭㰱㰲㰷㰼㰯㱦㱩㱥㱬㱤㰾㰊㰼㱦㱩㱥㱬㱤㰠㱮㱡㱭㱥㰽㰢㱔㱲㱡㱣㱥㱡㱢㱩㱬㱩㱴㱹㸢㰱㰳㱖㱖㱖㰭㰭㰭㰭㰭㰭㰭㰭㰭㰭㰭㰭㰭㰭㰭㰭㰰㰰㰼㰯㱦㱩㱥㱬㱤㰾㰊㰼㱦㱩㱥㱬㱤㰠㱮㱡㱭㱥㰽㰢㱄㱥㱳㱣㱲㱩㱰㱴㱩㱯㱮㸢㱄㱥㱳㱣㱲㱩㱰㱴㱩㱯㱮㰀㰼㰯㱦㱩㱥㱬㱤㰾㰊㰼㰯㱰㱡㱧㱥㰾㰊㰼㰯㱤㱯㱣㰾㰊

我不知道如何将 2 字节字符附加到此文件。

【问题讨论】:

  • " 打印一个 2 字节字符 " 那是什么?一个 16 位 wchar_t 还是什么?

标签: c linux unix unicode character-encoding


【解决方案1】:

UTF-16 字符不一定是 2 个字节宽。可能是 2 个字节 或 4 个字节 (read up here)。

您发布的奇怪输出很可能是附加 wchar_ts 的结果 直接到文件中,生成字节顺序为的 UTF-16 字符 右边的相反,这些 UTF-16 字符位于 UTF-16 范围的“东方”高度。

从您的问题标签中假设您在 Linux 上使用 GCC, 您可以通过包含&lt;inconv.h&gt; 来使用iconv 库来导入 一个字符编码转换api。这是一个样本程序 转换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 字节宽。

&lt;iconv.h&gt; 的文档是 here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 2016-10-23
    • 2010-12-10
    • 2017-10-22
    相关资源
    最近更新 更多