MultiByteToWideChar 函式 (stringapiset.h)

將字元字串對應至UTF-16 (寬字元) 字串。 字元字串不一定來自多位元組位元集。

謹慎 使用 MultiByteToWideChar 函式不正確可能會危害應用程式的安全性。 呼叫此函式可以輕鬆地造成緩衝區溢出,因為 lpMultiByteStr 所指示的輸入緩衝區大小等於字串中的位元組數目,而 lpWideCharStr 所指示的輸出緩衝區大小等於字元數。 若要避免緩衝區溢出,您的應用程式必須指定適合緩衝區接收之數據類型的緩衝區大小。 如需詳細資訊,請參閱 安全性考慮:國際功能
 
注意 ANSI 代碼頁在不同的計算機上可能不同,也可以變更單一計算機,導致數據損毀。 針對最一致的結果,應用程式應該使用 Unicode,例如 UTF-8 或 UTF-16,而不是特定的代碼頁,除非舊版標準或數據格式防止使用 Unicode。 如果無法使用 Unicode,當通訊協定允許時,應用程式應該以適當的編碼名稱標記數據流。 HTML 和 XML 檔案允許標記,但文字檔則不允許。
 

語法

int MultiByteToWideChar(
  [in]            UINT                              CodePage,
  [in]            DWORD                             dwFlags,
  [in]            _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr,
  [in]            int                               cbMultiByte,
  [out, optional] LPWSTR                            lpWideCharStr,
  [in]            int                               cchWideChar
);

參數

[in] CodePage

執行轉換時所使用的代碼頁。 此參數可以設定為操作系統中已安裝或可用之任何代碼頁的值。 如需代碼頁的清單,請參閱 代碼頁標識碼。 您的應用程式也可以指定下表所示的其中一個值。

意義
CP_ACP
系統預設的 Windows ANSI 代碼頁。
注意 此值在不同的計算機上可能不同,即使是在同一個網路上也一樣。 它可以在同一部計算機上變更,導致儲存的數據變得無法復原損毀。 此值僅供暫時使用,且永久記憶體應該盡可能使用UTF-16或UTF-8。
 
CP_MACCP
目前的系統 Macintosh 代碼頁。
注意 此值在不同的計算機上可能不同,即使是在同一個網路上也一樣。 它可以在同一部計算機上變更,導致儲存的數據變得無法復原損毀。 此值僅供暫時使用,且永久記憶體應該盡可能使用UTF-16或UTF-8。
 
注意 此值主要用於舊版程序代碼中,而且通常不需要,因為新式Macintosh計算機使用Unicode進行編碼。
 
CP_OEMCP
目前的系統 OEM 代碼頁。
注意 此值在不同的計算機上可能不同,即使是在同一個網路上也一樣。 它可以在同一部計算機上變更,導致儲存的數據變得無法復原損毀。 此值僅供暫時使用,且永久記憶體應該盡可能使用UTF-16或UTF-8。
 
CP_SYMBOL
符號代碼頁 (42) 。
CP_THREAD_ACP
目前線程的 Windows ANSI 代碼頁。
注意 此值在不同的計算機上可能不同,即使是在同一個網路上也一樣。 它可以在同一部計算機上變更,導致儲存的數據變得無法復原損毀。 此值僅供暫時使用,且永久記憶體應該盡可能使用UTF-16或UTF-8。
 
CP_UTF7
UTF-7。 只有在強制使用 7 位傳輸機制時,才使用此值。 建議使用UTF-8。
CP_UTF8
UTF-8。

[in] dwFlags

指出轉換類型的旗標。 應用程式可以指定下列值的組合,MB_PRECOMPOSED為預設值。 MB_PRECOMPOSED和MB_COMPOSITE互斥。 不論其他旗標的狀態為何,都可以設定MB_USEGLYPHCHARS和MB_ERR_INVALID_CHARS。

意義
MB_COMPOSITE 一律使用分解字元,也就是基底字元和一或多個非步調字元的字元,每個字元都有相異的程式代碼點值。 例如,Ä 是以 A + ー:拉丁大寫字母 A (U+0041) + 合併 DIAERESIS (U+0308) 。 請注意,此旗標不能與 MB_PRECOMPOSED搭配使用。
MB_ERR_INVALID_CHARS 如果遇到無效的輸入字元,則失敗。

從 Windows Vista 開始,如果應用程式未設定此旗標,則函式不會卸除不合法的字碼點,而是以 U+FFFD 取代不合法的序列, (針對指定的代碼頁編碼) 。

Windows 2000 SP4 和更新版本 Windows XP: 如果未設定此旗標,函式會以無訊息方式卸除不合法的程式代碼點。 呼叫 GetLastError 會傳回ERROR_NO_UNICODE_TRANSLATION。
MB_PRECOMPOSED
預設;請勿搭配使用 MB_COMPOSITE。 一律使用先行編譯字元,也就是基底或非步調字元組合具有單一字元值的字元。 例如,在字元 è 中,e 是基底字元,而輔色符號是非步調字元。 如果為字元定義單一 Unicode 字碼點,應用程式應該使用它,而不是個別的基底字元和非步調字元。 例如,Ä 是以單一 Unicode 字碼點 LATIN 大寫字母 A WITH DIAERESIS (U+00C4) 表示。
MB_USEGLYPHCHARS
使用字元,而不是控制字元。

針對下列代碼頁, dwFlags 必須設定為 0。 否則,函式會因為 ERROR_INVALID_FLAGS而失敗。

  • 50220
  • 50221
  • 50222
  • 50225
  • 50227
  • 50229
  • 57002 到 57011
  • 65000 (UTF-7)
  • 42 (符號)

注意

 針對UTF-8或代碼頁 54936 (GB18030,從 Windows Vista) 開始, dwFlags 必須設定為 0MB_ERR_INVALID_CHARS。 否則,函式會因為 ERROR_INVALID_FLAGS而失敗。

[in] lpMultiByteStr

要轉換之字元字串的指標。

[in] cbMultiByte

lpMultiByteStr 參數所指示之字串的大小,以位元組為單位。 或者,如果字串為 null 終止,則可以將此參數設定為 -1。 請注意,如果 cbMultiByte0,則函式會失敗。

如果此參數為 -1,函式會處理整個輸入字串,包括終止的 Null 字元。 因此,產生的 Unicode 字串具有終止 Null 字元,而函式傳回的長度會包含這個字元。

如果此參數設定為正整數,則函式會完全處理指定的位元元組數目。 如果提供的大小不包含終止的 Null 字元,則產生的 Unicode 字串不會以 Null 結尾,而且傳回的長度不包含此字元。

[out, optional] lpWideCharStr

接收已轉換字串之緩衝區的指標。

[in] cchWideChar

大小,以字元為單位,以 lpWideCharStr 表示的緩衝區。 如果此值為 0,則函式會傳回所需的緩衝區大小,以字元為單位,包括任何終止的 Null 字元,而且不會使用 lpWideCharStr 緩衝區。

傳回值

如果成功,會傳回寫入至 lpWideCharStr 所指示之緩衝區的字元數。 如果函式成功且 cchWideChar0,則傳回值會是 lpWideCharStr 所指示緩衝區的必要大小,以字元為單位。 另請參閱 dwFlags ,以取得當輸入無效的序列時 ,MB_ERR_INVALID_CHARS 旗標如何影響傳回值的相關信息。

如果函式不成功,函式會 0 傳回 。 若要取得擴充的錯誤資訊,應用程式可以呼叫 GetLastError,這可以傳回下列其中一個錯誤碼:

  • ERROR_INSUFFICIENT_BUFFER:提供的緩衝區大小不夠大,或設定不正確。NULL
  • ERROR_INVALID_FLAGS:為旗標的值無效。
  • ERROR_INVALID_PARAMETER:任何參數值都無效。
  • ERROR_NO_UNICODE_TRANSLATION:在字串中找到無效的 Unicode。

備註

此函式的預設行為是轉譯為輸入字元字串的預先編譯形式。 如果預先編譯的窗體不存在,函式會嘗試轉譯成復合表單。

MB_PRECOMPOSED旗標的使用對大部分代碼頁的影響很小,因為大部分的輸入數據都已經組成。 使用 MultiByteToWideChar 轉換之後,請考慮呼叫 NormalizeStringNormalizeString 提供更精確、標準和一致的數據,而且也可以更快。 請注意,針對傳遞至 NormalizeStringNORM_FORM 列舉,NormalizationC 會對應至MB_PRECOMPOSED,而 NormalizationD 會對應至MB_COMPOSITE。

如上述警告所述,如果第一次呼叫此函式且 cchWideChar 設定 0 為 ,以取得所需的大小,則輸出緩衝區可以輕鬆地過度執行。 如果使用MB_COMPOSITE旗標,則每個輸入字元的輸出長度可以是三或多個字元。

lpMultiByteStrlpWideCharStr 指標不得相同。 如果相同,函式會失敗,而 GetLastError 會傳回值ERROR_INVALID_PARAMETER。

如果明確指定輸入字串長度,但未終止 Null 字元,MultiByteToWideChar 就不會終止輸出字串。 若要以 Null 結束此函式的輸出字串,應用程式應該傳入 -1,或明確計算輸入字串的終止 Null 字元。

如果已設定MB_ERR_INVALID_CHARS,且來源字串中遇到無效字元,則函式會失敗。 無效的字元是下列其中一項:

  • 不是來源字串中預設字元的字元,但在未設定MB_ERR_INVALID_CHARS時會轉譯為預設字元。
  • 若為 DBCS 字串,則為具有前置位元組但沒有有效尾端位元組的字元。

從 Windows Vista 開始,此函式完全符合 UTF-8 和 UTF-16 的 Unicode 4.1 規格。 在舊版操作系統上使用的函式會編碼或譯碼 lone Surrogate halves 或不相符的 Surrogate 字組。 以舊版 Windows 撰寫的程式代碼,依賴此行為來編碼隨機非文字二進位數據可能會發生問題。 不過,在有效的 UTF-8 字串上使用此函式的程式代碼,的行為會與先前的 Windows 作業系統相同。

Windowsxp: 為避免非最短格式 UTF-8 字元版本的安全性問題, MultiByteToWideChar 會刪除這些字元。

從 Windows 8:MultiByteToWideChar 開始,會在 中Stringapiset.h宣告。 在 Windows 8 之前,已在中Winnls.h宣告。

程式碼範例

catch (std::exception e)
{
    // Save in-memory logging buffer to a log file on error.

    ::std::wstring wideWhat;
    if (e.what() != nullptr)
    {
        int convertResult = MultiByteToWideChar(CP_UTF8, 0, e.what(), (int)strlen(e.what()), NULL, 0);
        if (convertResult <= 0)
        {
            wideWhat = L"Exception occurred: Failure to convert its message text using MultiByteToWideChar: convertResult=";
            wideWhat += convertResult.ToString()->Data();
            wideWhat += L"  GetLastError()=";
            wideWhat += GetLastError().ToString()->Data();
        }
        else
        {
            wideWhat.resize(convertResult + 10);
            convertResult = MultiByteToWideChar(CP_UTF8, 0, e.what(), (int)strlen(e.what()), &wideWhat[0], (int)wideWhat.size());
            if (convertResult <= 0)
            {
                wideWhat = L"Exception occurred: Failure to convert its message text using MultiByteToWideChar: convertResult=";
                wideWhat += convertResult.ToString()->Data();
                wideWhat += L"  GetLastError()=";
                wideWhat += GetLastError().ToString()->Data();
            }
            else
            {
                wideWhat.insert(0, L"Exception occurred: ");
            }
        }
    }
    else
    {
        wideWhat = L"Exception occurred: Unknown.";
    }

    Platform::String^ errorMessage = ref new Platform::String(wideWhat.c_str());
    // The session added the channel at level Warning. Log the message at
    // level Error which is above (more critical than) Warning, which
    // means it will actually get logged.
    _channel->LogMessage(errorMessage, LoggingLevel::Error);
    SaveLogInMemoryToFileAsync().then([=](StorageFile^ logFile) {
        _logFileGeneratedCount++;
        StatusChanged(this, ref new LoggingScenarioEventArgs(LoggingScenarioEventType::LogFileGenerated, logFile->Path->Data()));
    }).wait();
}

GitHub 上的 Windows 通用範例

規格需求

需求
最低支援的用戶端 Windows 2000 專業版 [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows 2000 Server [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 stringapiset.h (包含 Windows.h)
程式庫 Kernel32.lib
DLL Kernel32.dll

另請參閱

Unicode 和字元集函式

Unicode 和字元集

WideCharToMultiByte

VBS 記憶體保護區中可用的 Vertdll API