簡體   English   中英

需要將字符串轉換為 UTF8 字符串

[英]Required to convert a String to UTF8 string

問題陳述:我需要將生成的字符串轉換為UTF8字符串,這個生成的字符串擴展了ascii字符,我在Linux系統(2.6.32-358.el6.x86_64)上。

POC 仍在進行中,所以我只能提供小代碼示例,完整的解決方案只能在准備好后發布。

為什么我需要 UFT8(我擴展了 ascii 字符以存儲在必須是 UTF8 的字符串中)。

我是如何進行的:

  • 將生成的字符串轉換為 wchar_t 字符串。

請看下面的示例代碼

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);
}

這里有一個問題:

輸出是

普羅娃????

  1. 為什么這里沒有打印尺寸?
  2. 為什么第二個 printf 只打印一個字符。
  3. 如果我在打印的兩個字符串之前打印 size ,那么只打印 5 並且兩個字符串都從控制台中丟失。


進入第二部分:

現在我將有一個 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在此處輸入圖片說明

對於您的第一個問題(我將其解釋為“為什么所有輸出都不是我所期望的”):

  1. '?????' 在哪里? 來自? 在調用mbstowcs(WcharString, CharString, strlen(CharString)) ,最后一個參數 ( strlen(CharString) ) 是輸出緩沖區的長度,而不是輸入字符串的長度。 mbstowcs不會寫入超過該數量的寬字符,包括 NUL 終止符 由於轉換需要包括終止符在內的 6 個寬字符,並且您只允許它寫入 5 個寬字符,因此生成的寬字符串不會以 NUL 終止,並且當您嘗試將其打印出來時,您最終會在結束后打印垃圾轉換后的字符串。 因此????? . 您應該使用wchar_t中的輸出緩沖區的大小(在本例中為 255)。

  2. 為什么第二個wprintf只打印一個字符? 當您使用寬字符串參數調用wprintf時,您必須使用%ls格式代碼(或者,更准確地說, %s轉換需要用l長度修飾符限定)。 如果您使用%s而不使用l ,則wprintf會將字符串解釋為char* ,並且在輸出時會將每個字符轉換為wchar_t 然而,由於參數實際上是一個寬字符串,字符串中的第一個wchar_tL"p" ,它是某個整數大小的數字0x70 這意味着,第二個字節wchar_t (從結尾開始計算,因為你有一個小端架構)是0,所以如果你把字符串作為字符的字符串,它會立即終止后p 所以只打印一個字符。

  3. 為什么最后一個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.

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