簡體   English   中英

如何使用iconv(3)將寬字符串轉換為UTF-8?

[英]How to use iconv(3) to convert wide string to UTF-8?

我正在嘗試使用iconv(3)將寬字符串轉換為UTF-8,使用下面的代碼。 當我運行下面的內容時,iconv調用返回E2BIG,就好像輸出緩沖區中沒有足夠的可用空間字節一樣。 盡管事實上(我認為)我確定了輸出緩沖區的大小以承認UTF-8的最壞情況擴展,但這種情況仍然存在。 實際上,假設輸入是一個簡單的ASCII“A”編碼為wchar_t后跟一個零wchar_t終結符,輸出應該是兩個字節/字符:一個'A'后跟一個'\\ 0'。

我的Linux系統上的'man utf-8'表示UTF-8字節序列的最大長度是6個字節,所以我相信對於2個wchar_ts的輸入緩沖區(一個字符后跟空終止符),make(on我的系統)總共8個字節(因為sizeof(wchar_t)== 4),12個字節的緩沖區(2 * UTF8_SEQUENCE_MAXLEN)就足夠了。

通過實驗,如果我將UTF8_SEQUENCE_MAXLEN增加到16,則iconv的返回值表示成功(15仍然失敗)。 但是當我用UTF-8編碼時,我看不出任何wchar_t值占用這么多字節的方式。

我的計算出錯了嗎? 16字節的UTF-8序列是否可行? 我做錯了什么?

#include <stdio.h>
#include <stdlib.h>
#include <iconv.h>
#include <wchar.h>

#define UTF8_SEQUENCE_MAXLEN 6
/* #define UTF8_SEQUENCE_MAXLEN 16 */

int
main(int argc, char **argv)
{
    wchar_t *wcs = L"A";
    signed char utf8[(1 /* wcslen(wcs) */ + 1 /* L'\0' */) * UTF8_SEQUENCE_MAXLEN];
    char *iconv_in = (char *) wcs;
    char *iconv_out = (char *) &utf8[0];
    size_t iconv_in_bytes = (wcslen(wcs) + 1 /* L'\0' */) * sizeof(wchar_t);
    size_t iconv_out_bytes = sizeof(utf8);
    size_t ret;
    iconv_t cd;

    cd = iconv_open("WCHAR_T", "UTF-8");
    if ((iconv_t) -1 == cd) {
        perror("iconv_open");
        return EXIT_FAILURE;
    }

    ret = iconv(cd, &iconv_in, &iconv_in_bytes, &iconv_out, &iconv_out_bytes);
    if ((size_t) -1 == ret) {
        perror("iconv");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

iconv_open的參數是錯誤的。 參數的順序是(to,from),而不是(from,to),如聯機幫助頁中明確說明的那樣。

因此,改變

iconv_open("WCHAR_T", "UTF-8");

iconv_open("UTF-8", "WCHAR_T");

導致上面的代碼(否則未更改)按預期工作。

D'哦。 需要更仔細地閱讀聯機幫助頁。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM