5

Linuxプログラムに読み込みたいUNICODE-16文字列を含むファイルがあります。文字列は、Windowsの内部WCHAR形式から生で書き込まれました。(Windowsは常にUTF-16を使用しますか?たとえば、日本語版)

生の読み取りとwcstombs_lによる変換を使用してそれらを読み取ることができると思います。ただし、使用するロケールがわかりません。最新のUbuntuおよびMacOSXマシンで「locale-a」を実行すると、名前にutf-16が含まれるロケールはゼロになります。

もっと良い方法はありますか?

更新:正解と以下の他のものは、私がlibiconvを使用することを指摘するのに役立ちました。これが私が変換を行うために使用している関数です。私は現在、1行のコードに変換するクラス内にそれを持っています。

// 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()
4

4 に答える 4

6

最も簡単な方法は、ファイルをutf16からutf8ネイティブUNIXエンコーディングに変換してから、それを読み取ることです。

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

iconv(3)(man 3 iconvを参照)を使用して、Cを使用して文字列を変換することもできます。他のほとんどの言語には、iconvへのバインディングもあります。

ほとんどのLinuxディストリビューションでは通常デフォルトのen_US.UTF-8などのUTF-8ロケールを使用できます。

于 2009-02-05T19:41:26.760 に答える
4

(Windows は常に UTF-16 を使用しますか? たとえば、日本語版では)

はい、NT の WCHAR は常に UTF-16LE です。

(日本語のインストールでは cp932/Shift-JIS である「システム コードページ」は、Unicode ネイティブではない非常に多くのアプリケーションや FAT32 パスなどのために、NT にまだ存在します。)

ただし、wchar_t は 16 ビットであることが保証されておらず、Linux では保証されず、UTF-32 (UCS-4) が使用されます。したがって、wcstombs_l が満足する可能性は低いです。

正しいことは、iconv のようなライブラリを使用して、内部で使用している形式 (おそらく wchar_t) に読み込むことです。バイトを突っ込んで自分でハックしようとすることもできますが、おそらくサロゲートのようなものを間違えるでしょう.

最新の Ubuntu および Mac OS X マシンで「locale -a」を実行すると、名前に utf-16 を含むゼロ ロケールが生成されます。

実際、Linux はすべての \0 のおかげで、ロケールのデフォルト エンコーディングとして UTF-16 を使用できません。

于 2009-02-05T18:43:50.400 に答える
1

プログラムの内部表現として Unicode エンコーディングを使用することを強くお勧めします。UTF-16 または UTF-8 のいずれかを使用します。内部で UTF-16 を使用する場合、当然、変換は必要ありません。UTF-8 を使用する場合は、.UTF-8などのロケールを使用できますen_US.UTF-8

于 2009-02-05T17:20:57.683 に答える