[英]Required to convert a String to UTF8 string
問題陳述:我需要將生成的字符串轉換為UTF8字符串,這個生成的字符串擴展了ascii字符,我在Linux系統(2.6.32-358.el6.x86_64)上。
POC 仍在進行中,所以我只能提供小代碼示例,完整的解決方案只能在准備好后發布。
為什么我需要 UFT8(我擴展了 ascii 字符以存儲在必須是 UTF8 的字符串中)。
我是如何進行的:
請看下面的示例代碼
int main(){
char CharString[] = "Prova";
iconv_t cd;
wchar_t WcharString[255];
size_t size= mbstowcs(WcharString, CharString, strlen(CharString));
wprintf(L"%ls\n", WcharString);
wprintf(L"%s\n", WcharString);
printf("\n%zu\n",size);
}
這里有一個問題:
輸出是
普羅娃????
秒
現在我將有一個 wchar_t 字符串,我想將其轉換為 UTF8 字符串
為此,我正在瀏覽並發現 iconv 會在這里有所幫助。
問題在這里這些是我在 手冊中找到的方法
**iconv_t iconv_open(const char *, const char *); size_t iconv(iconv_t, char **, size_t *, char **, size_t *); int iconv_close(iconv_t);**
在喂給 iconv 之前,我是否需要將 wchar_t 數組轉換回 char 數組?
請就上述問題提出建議。
我正在談論的擴展 ascii 請參見下面標記快照中的字母 i
對於您的第一個問題(我將其解釋為“為什么所有輸出都不是我所期望的”):
'?????' 在哪里? 來自? 在調用mbstowcs(WcharString, CharString, strlen(CharString))
,最后一個參數 ( strlen(CharString)
) 是輸出緩沖區的長度,而不是輸入字符串的長度。 mbstowcs
不會寫入超過該數量的寬字符,包括 NUL 終止符。 由於轉換需要包括終止符在內的 6 個寬字符,並且您只允許它寫入 5 個寬字符,因此生成的寬字符串不會以 NUL 終止,並且當您嘗試將其打印出來時,您最終會在結束后打印垃圾轉換后的字符串。 因此?????
. 您應該使用wchar_t
中的輸出緩沖區的大小(在本例中為 255)。
為什么第二個wprintf
只打印一個字符? 當您使用寬字符串參數調用wprintf
時,您必須使用%ls
格式代碼(或者,更准確地說, %s
轉換需要用l
長度修飾符限定)。 如果您使用%s
而不使用l
,則wprintf
會將字符串解釋為char*
,並且在輸出時會將每個字符轉換為wchar_t
。 然而,由於參數實際上是一個寬字符串,字符串中的第一個wchar_t
是L"p"
,它是某個整數大小的數字0x70
。 這意味着,第二個字節wchar_t
(從結尾開始計算,因為你有一個小端架構)是0,所以如果你把字符串作為字符的字符串,它會立即終止后p
。 所以只打印一個字符。
為什么最后一個printf
打印任何東西? 在 C 中,輸出流可以是寬流或字節流,但您在打開流時沒有指定。 (而且,無論如何,標准輸出已經為您打開了。)這稱為流的方向。 新打開的流是無方向的,當您第一次輸出到流時方向是固定的。 如果第一個輸出調用是寬調用,如wprintf
,則流是寬流; 否則,它是一個字節流。 一旦設置,方向就固定了,您不能使用錯誤方向的輸出調用。 所以printf
是非法的,它除了引發錯誤之外什么也不做。
現在,讓我們繼續你的第二個問題:我該怎么辦?
第一件事是你需要清楚輸入的格式是什么,以及你想如何輸出它。 在 Linux 上,您不太可能想要使用wchar_t
。 輸入字符串最可能的情況是它已經是 UTF-8,或者它是某種 ISO-8859-x 編碼。 輸出的最可能情況是相同的:要么是 UTF-8,要么是某種 ISO-8859-x 編碼。
不幸的是,您的程序無法知道控制台期望的是什么編碼。 輸出甚至可能不會進入控制台。 同樣,您的程序確實無法知道輸入字符串中使用的是哪種 ISO-8859-x 編碼。 (如果它是字符串文字,則可能會在調用編譯器時指定編碼,但沒有提供信息的標准方法。)
如果由於非 ascii 字符顯示不正確而無法查看輸出,則應首先確保將控制台配置為使用與程序輸出相同的編碼。 如果程序將 UTF-8 發送到顯示 ISO-8859-15 的控制台,則文本將無法正確顯示。 理論上,您的區域設置包括您的控制台使用的編碼,但如果您使用的是遠程控制台(例如,通過 Windows 機器上的 PuTTY),則控制台不是 Linux 環境的一部分,默認區域設置可能不正確. 最簡單的解決方法是正確配置您的控制台,但也可以更改 Linux 區域設置。
您從字節字符串使用mbstowcs
的事實表明您相信原始字符串是 UTF-8。 因此,問題似乎不太可能是您需要將其轉換為UTF-8。
您當然可以使用iconv
將字符串從一種編碼轉換為另一種編碼; 你不需要通過wchar_t
來這樣做。 但是您確實需要知道實際的輸入編碼和所需的輸出編碼。
對 utf8 使用 iconv 不是一個好主意。 自己實現utf8的定義就行了。 從描述https://en.wikipedia.org/wiki/UTF-8用 C 語言很容易做到這一點。 您甚至不需要 wchar_t,只需將 uint32_t 用於您的角色。 如果您自己實現,您將學到很多東西,並且您的程序將通過不使用 mb 或 iconv 函數來提高速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.