繁体   English   中英

如何在Linux中使用POSIX方法从文件中读取Unicode-16字符串?

[英]How do I read Unicode-16 strings from a file using POSIX methods in Linux?

我有一个包含UNICODE-16字符串的文件,我想将其读入Linux程序。 字符串是从Windows的内部WCHAR格式原始编写的。 (Windows是否总是使用UTF-16?例如日文版)

我相信我可以使用原始读取和使用wcstombs_l进行转换来读取它们。 但是,我无法确定要使用的语言环境。 在我最新的Ubuntu和Mac OS X机器上运行“locale -a”会产生零区域设置,其名称中包含utf-16。

有没有更好的办法?

更新:正确的答案和下面的其他人帮助我指向使用libiconv。 这是我用来进行转换的功能。 我目前在一个类中将它转换为一行代码。

// Function for converting wchar_t* to char*. (Really: UTF-16LE --> UTF-8)
// It will allocate the space needed for dest. The caller is
// responsible for freeing the memory.
static int iwcstombs_alloc(char **dest, const wchar_t *src)
{
  iconv_t cd;
  const char from[] = "UTF-16LE";
  const char to[] = "UTF-8";

  cd = iconv_open(to, from);
  if (cd == (iconv_t)-1)
  {
    printf("iconv_open(\"%s\", \"%s\") failed: %s\n",
           to, from, strerror(errno));
    return(-1);
  }

  // How much space do we need?
  // Guess that we need the same amount of space as used by src.
  // TODO: There should be a while loop around this whole process
  //       that detects insufficient memory space and reallocates
  //       more space.
  int len = sizeof(wchar_t) * (wcslen(src) + 1);

  //printf("len = %d\n", len);

  // Allocate space
  int destLen = len * sizeof(char);
  *dest = (char *)malloc(destLen);
  if (*dest == NULL)
  {
    iconv_close(cd);
    return -1;
  }

  // Convert

  size_t inBufBytesLeft = len;
  char *inBuf = (char *)src;
  size_t outBufBytesLeft = destLen;
  char *outBuf = (char *)*dest;

  int rc = iconv(cd,
                 &inBuf,
                 &inBufBytesLeft,
                 &outBuf,
                 &outBufBytesLeft);
  if (rc == -1)
  {
    printf("iconv() failed: %s\n", strerror(errno));
    iconv_close(cd);
    free(*dest);
    *dest = NULL;
    return -1;
  }

  iconv_close(cd);

  return 0;
} // iwcstombs_alloc()

最简单的方法是将文件从utf16转换为utf8本机UNIX编码,然后读取它,

iconv -f utf16 -t utf8 file_in.txt -o file_out.txt

您还可以使用iconv(3)(请参阅man 3 iconv)使用C转换字符串。大多数其他语言也绑定到iconv。

您可以使用任何UTF-8语言环境,如en_US.UTF-8,它们通常是大多数Linux发行版的默认语言环境。

(Windows是否总是使用UTF-16?例如日文版)

是的,NT的WCHAR总是UTF-16LE。

(对于日语安装的'系统代码页'确实是cp932 / Shift-JIS,仍然存在于NT中,以获得许多非Unicode本地,FAT32路径等应用程序的好处。)

但是,wchar_t不保证是16位,而在Linux上它不会,使用UTF-32(UCS-4)。 所以wcstombs_l不太可能幸福。

正确的事情是使用像iconv这样的库来读取你在内部使用的任何格式 - 大概是wchar_t。 可以尝试通过戳入字节来自己破解它,但你可能会得到像Surrogates这样的东西。

在我最新的Ubuntu和Mac OS X机器上运行“locale -a”会产生零区域设置,其名称中包含utf-16。

实际上,由于所有的\\ 0,Linux无法使用UTF-16作为语言环境默认编码。

您可以阅读二进制文件,然后进行自己的快速转换: http//unicode.org/faq/utf_bom.html#utf16-3但是使用可以正确处理无效序列的库(如libiconv)可能更安全。

我强烈建议使用Unicode编码作为程序的内部表示。 使用UTF-16或UTF-8。 如果您在内部使用UTF-16,那么显然不需要翻译。 如果使用UTF-8,则可以使用带有.UTF-8的语言环境,例如en_US.UTF-8

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM