使用iconv在C中将Unicode代码点转换为UTF-8

Converting Unicode codepoints to UTF-8 in C using iconv

我想将表示 Unicode 代码点的 32 位值转换为 char 序列,它是仅包含与代码点对应的字符的 utf-8 编码字符串。

比如我想把值955转成utf-8编码的字符串"λ".

我尝试使用 iconv 执行此操作,但无法获得所需的结果。这是我写的代码:

#include <stdio.h>
#include <iconv.h>
#include <stdint.h>

int main(void)
{
  uint32_t codepoint = U'λ';
  char *input = (char *) &codepoint;
  size_t in_size = 2; // lower-case lambda is a 16-bit character (0x3BB = 955)

  char output_buffer[10];
  char *output = output_buffer;
  size_t out_size = 10;

  iconv_t cd = iconv_open("UTF-8", "UTF-32");

  iconv(cd, &input, &in_size, &output, &out_size);

  puts(output_buffer);

  return 0;
}

当我运行它时,只打印一个换行符(puts自动打印一个换行符,--outout_buffer的第一个字节是'[=17=]')。

我的理解或实现有什么问题?

两个问题:

  1. 由于您使用的是 UTF-32,因此需要指定 4 个字节。 “小写 lambda 是 16 位字符 (0x3BB = 955)”的注释对于 4 字节固定宽度编码是不正确的;它是 0x000003bb。设置 size_t in_size = 4;.

  2. iconv 不会为您添加空终止符;它调整它给出的指针。在调用 puts.

    之前,您需要添加自己的
    *output = '[=10=]';
    puts(output_buffer);
    

正如 minitech 所说,对于 uint32_t 中的 UTF32,您必须使用 size = 4,并且您必须将缓冲区预设为 null,以便在转换后具有终止 null。

此代码适用于 Ubuntu :

#include <stdio.h>
#include <iconv.h>
#include <stdint.h>
#include <memory.h>

int main(void)
{
  uint32_t codepoint = 955;
  char *input = (char *) &codepoint;
  size_t in_size = 4; // lower-case lambda is a 16-bit character (0x3BB = 955)

  char output_buffer[10];
  memset(output_buffer, 0, sizeof(output_buffer));
  char *output = output_buffer;
  size_t out_size = 10;

  iconv_t cd = iconv_open("UTF-8", "UTF-32");

  iconv(cd, &input, &in_size, &output, &out_size);

  puts(output_buffer);

  return 0;
}