使用iconv

时间:2015-05-25 20:44:46

标签: c unicode encoding utf-8 iconv

我想将一个代表Unicode代码点的32位值转换为char s的序列,这是一个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的第一个字节为'\0')。

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

2 个答案:

答案 0 :(得分:3)

正如minitech所说,您必须在size = 4中使用uint32_t作为UTF32,并且必须将缓冲区预设为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;
}

答案 1 :(得分:2)

两个问题:

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

  2. iconv不会为您添加空终结符;它会调整指定的指针。在调用puts之前,您需要添加自己的内容。

    *output = '\0';
    puts(output_buffer);