【问题标题】:Creating file that uses UTF-8 encoding创建使用 UTF-8 编码的文件
【发布时间】:2016-01-12 09:18:04
【问题描述】:

我正在尝试创建一个文件并使用 C 以 UTF-8 格式对其内容进行编码。我尝试了几件事并环顾四周,但似乎找不到问题的解决方案.

这是我目前正在尝试的代码(u8_wc_tout8函数取自here):

int u8_wc_toutf8(char *dest, u_int32_t ch)
{
    if (ch < 0x80) {
        dest[0] = (char)ch;
        return 1;
    }
    if (ch < 0x800) {
        dest[0] = (ch>>6) | 0xC0;
        dest[1] = (ch & 0x3F) | 0x80;
        return 2;
    }
    if (ch < 0x10000) {
        dest[0] = (ch>>12) | 0xE0;
        dest[1] = ((ch>>6) & 0x3F) | 0x80;
        dest[2] = (ch & 0x3F) | 0x80;
        return 3;
    }
    if (ch < 0x110000) {
        dest[0] = (ch>>18) | 0xF0;
        dest[1] = ((ch>>12) & 0x3F) | 0x80;
        dest[2] = ((ch>>6) & 0x3F) | 0x80;
        dest[3] = (ch & 0x3F) | 0x80;
        return 4;
    }
    return 0;
}
int main ()
{

    printf(setlocale(LC_ALL, "")); //Prints C.UTF-8

    FILE * fout;
    fout=fopen("out.txt","w");

    u_int32_t c = 'Å';
    char convertedChar[6];
    int cNum = u8_wc_toutf8(convertedChar, c);

    printf(convertedChar); //Prints ?
    fprintf(fout, convertedChar); 
    fclose(fout);

    printf("\nFile has been created...\n");
    return 0;
}

当我从 Windows 中的命令提示符运行它时,它会打印 ?,当我打开创建的文件时,我会得到一些奇怪的字符。如果我在 Firefox 中检查文件上的编码,它会显示:

“windows-1252”

有没有更好的方法来检查文件的编码?

任何能指引我正确方向的提示都会非常好,感觉这应该不难做到。

【问题讨论】:

  • c 库具有多字节字符类型 wchar 和用于处理 utf 和其他多字节字符集的相关函数。 en.wikibooks.org/wiki/C_Programming/C_Reference/wchar.h
  • 您还没有为convertedChar 分配任何内存。因此,该指针指向未定义的内存位置,您会得到 未定义的行为(= 任何事情都可能发生)。将convertedChar 声明为数组而不是指针:char convertedChar[MAX_UTF8_CHAR_LENGTH];
  • @Kai Ikratsch 当我切换到 Widechar 时,它在 nodepad++ 中正确识别它,但由于某种原因仍然无法在 Firefox 中工作。遗憾的是,分配内存并没有帮助。
  • @KaiIskratsch wchar_t 不太擅长表示 Unicode。在某些实现中,该类型只有 16 位宽,这对于完整的 Unicode 范围来说是不够的。
  • @asiew 在十六进制编辑器中打开文件,并检查字节是否与预期值匹配。编辑器检测到编码错误并非闻所未闻,因此首先要确保文件实际上具有正确的数据。

标签: c encoding utf-8


【解决方案1】:

您应该为convertedChar 分配内存并将c 设置为197,这是埃字符(Å) 的unicode char id。然后,您现在可以根据需要将此字符编码为 utf-8 或其他任何内容:

int main ()
{
    FILE * fout;
    fout=fopen("out.txt","wb");

    u_int32_t c = 197; // Or 0xC5
    char convertedChar[4];
    int cNum = u8_wc_toutf8(convertedChar, c);

    fwrite(convertedChar, sizeof(char), cNum, fout);
    fclose(fout);

    printf("\nFile has been created...\n");
    return 0;
}

如果您的语言环境使用 UTF-8 编码,那么您可以使用它在控制台上打印字符:

wchar_t wc;
mbtowc(&wc, convertedChar, sizeof(wchar_t));
putwc(wc, stdout);

【讨论】:

  • 使用数字代码点是个好主意,因为这样源文件编码就不会成为问题。但是,我不知道你从哪里得到212(U+00D4 是 Ô)。 Å 应该是 U+00C5。
  • 我懒得为此写自己的答案:您还必须用更好的东西替换fprintf,因为1.它使用缓冲区作为格式字符串,2.该字符串是非空终止。
  • 确实,你不应该使用 fprintf。您想从convertedChar 缓冲区写入cNum 字符。这可以使用fwrite(写入 n 个字符)或使用 fputc 的循环(写入 1 个字符)来完成,但不要使用 fprintf
  • 我建议你打开一个新的讨论并用你的“文本块”发布一个代码。
  • 什么是“未知文本块”? u8_wc_toutf8 函数将 one unicode 字符 id(ch - 始终为 4 个字节)转换为 其 UTF-8 编码 (convertedChar)。如果你想转换一个 Unicode 字符串(即一个 array 的 unicode 字符 id = 一个 32 位 整数的数组),你是否调用 @ 987654334@ 在循环中,或者直接调用 u8_toutf8
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
相关资源
最近更新 更多