将Unicode Unicode代码点保存为UTF-8文件

时间:2014-09-03 11:37:35

标签: c utf-8 io

上下文

Debian 64位 尝试将int(例如233)写入文件并使其文本打印为“é”。

问题

我无法理解如何编写一个utf8等效字符,例如“é”或任何比char类型更宽的UTF-8字符。该文件应该是人类可读的,可以通过网络发送。

我的目标是将int写入文件并获取其utf8等效值。

我不知道自己在做什么。

代码

FILE * dd = fopen("/myfile.txt","w");
fprintf(dd, "%s", 233); /* The file should print "é" */
fclose(dd);

由于

更新:

根据Biffen的评论,这是写“E9”的代码的另一个代码(“é”的十六进制值);

int p = 233;
char r[5];
sprintf(r,"%x",p);
printf("%s\n",r);
fwrite(r,1,strlen(r),dd);
fclose(dd);

如何将其转换为“é”?

更新最终工作代码:

UFILE * dd = u_fopen("/myfile.txt","wb", NULL, NULL);
UChar32 c = 233;
u_fputc(c,dd);
u_fclose(dd);

4 个答案:

答案 0 :(得分:5)

您似乎希望printf()了解UTF-8,但事实并非如此。

你可以自己实现UTF-8编码,毕竟这是一个非常简单的编码。

解决方案可能如下所示:

void put_utf8(FILE *f, uint32_t codepoint)
{
    if (codepoint <= 0x7f) {
       fprintf(f, "%c", (char) codepoint & 0x7f);
    }
    else if (codepoint <= 0x7ff) {
       fprintf(f, "%c%c", (char) (0xc0 | (codepoint >> 6)),
                          (char) (0x80 | (codepoint & 0x3f));
    }
    else if (codepoint <= 0xffff) {
       fprintf(f, "%c%c%c", (char) (0xe0 | (codepoint >> 12)),
                            (char) (0x80 | ((codepoint >> 6) & 0x3f),
                            (char) (0x80 | (codepoint & 0x3f));
    }
    else if (codepoint <= 0x1fffff) {
       fprintf(f, "%c%c%c%c", (char) (0xf0 | (codepoint >> 18)),
                              (char) (0x80 | ((codepoint >> 12) & 0x3f),
                              (char) (0x80 | ((codepoint >> 6) & 0x3f),
                              (char) (0x80 | (codepoint & 0x3f));
    }
    else {
        // invalid codepoint
    }
}

你会这样使用它:

FILE *f = fopen("mytext.txt", "wb");
put_utf8(f, 233);
fclose(f);

然后它会将两个字符0xC3和0xA9输出到f

有关UTF-8的详细信息,请参阅Wikipedia

答案 1 :(得分:3)

一种方法是:

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main(void){
    wchar_t utfchar = 233;
    setlocale(LC_CTYPE, "");
    wprintf(L"%lc\n", utfchar);
}

您只需找到要打印到文件的相应fprintf

答案 2 :(得分:1)

标准库有codecvt用于编码转换,但据我记得GCC,仍然没有完整的实现。 编辑:错过了标记。 codecvt是C ++。

将Unicode代码点转换为UTF-8单位序列的“算法”并不太复杂,因此您可以相当轻松地自己实现它。 Here是描述该过程的页面,here是另一个很好的资源。

但如果你知道你会做很多与Unicode有关的事情,我建议你使用一个库。 ICU是一个受欢迎的选择。

答案 3 :(得分:1)

您可以为GNU libunistring安装libunistring-dev个包,然后添加<unistr.h>并使用例如u32_to_u8函数将UCS-4字符串转换为UTF-8字符串。见libunistring documentation。也许使用<unistdio.h>