簡體   English   中英

如何將 const WCHAR * 轉換為 const char *

[英]how to convert const WCHAR * to const char *

CString output ;
const WCHAR* wc = L"Hellow World" ;
if( wc != NULL )
{   
     output.Append(wc);
}
printf( "output: %s\n",output.GetBuffer(0) );

你也可以試試這個:

#include <comdef.h>  // you will need this
const WCHAR* wc = L"Hello World" ;
_bstr_t b(wc);
const char* c = b;
printf("Output: %s\n", c);

_bstr_t實現了以下轉換操作符,我覺得這很方便:

operator const wchar_t*( ) const throw( ); 
operator wchar_t*( ) const throw( ); 
operator const char*( ) const; 
operator char*( ) const;

編輯:關於回答評論的澄清: line const char* c = b; 導致字符串的窄字符副本由_bstr_t實例創建和管理,該實例將在銷毀時釋放一次。 運算符只返回一個指向該副本的指針。 因此,無需復制此字符串。 此外,在問題中, CString::GetBuffer返回LPTSTR (即TCHAR* )而不是LPCTSTR (即const TCHAR* )。

另一種選擇是使用轉換宏:

USES_CONVERSION;
const WCHAR* wc = L"Hello World" ;
const char* c = W2A(wc);

這種方法的問題是轉換后的字符串的內存是在棧上分配的,所以字符串的長度是有限的。 但是,這一系列轉換宏允許您選擇用於轉換的代碼頁,如果寬字符串包含非 ANSI 字符,則通常需要這樣做。

為此,您可以使用sprintf

const char output[256];
const WCHAR* wc = L"Hellow World" ;
sprintf(output, "%ws", wc );

我的 Linux 代碼

// Debian GNU/Linux 8 "Jessie" (amd64)

#include <locale.h>
#include <stdlib.h>
#include <stdio.h>

// Use wcstombs(3) to convert Unicode-string (wchar_t *) to UTF-8 (char *)
// http://man7.org/linux/man-pages/man3/wcstombs.3.html

int f(const wchar_t *wcs) {
        setlocale(LC_ALL,"ru_RU.UTF-8");
        printf("Sizeof wchar_t: %d\n", sizeof(wchar_t));
        // on Windows, UTF-16 is internal Unicode encoding (UCS2 before WinXP)
        // on Linux, UCS4 is internal Unicode encoding
        for (int i = 0; wcs[i] > 0; i++) printf("%2d %08X\n",i,wcs[i]);
        char s[256];
        size_t len = wcstombs(s,wcs,sizeof(s));
        if (len > 0) {
                s[len] = '\0';
                printf("mbs: %s\n",s);
                for (int i = 0; i < len; i++)
                        printf("%2d %02X\n",i,(unsigned char)s[i]);
                printf("Size of mbs, in bytes: %d\n",len);
                return 0;
        }
        else return -1;
}

int main() {
        f(L"Привет"); // 6 symbols
        return 0;
}

如何構建

#!/bin/sh
NAME=`basename $0 .sh`
CC=/usr/bin/g++-4.9
INCS="-I."
LIBS="-L."
$CC ${NAME}.c -o _${NAME} $INCS $LIBS

輸出

$ ./_test 
Sizeof wchar_t: 4
 0 0000041F
 1 00000440
 2 00000438
 3 00000432
 4 00000435
 5 00000442
mbs: Привет
 0 D0
 1 9F
 2 D1
 3 80
 4 D0
 5 B8
 6 D0
 7 B2
 8 D0
 9 B5
10 D1
11 82
Size of mbs, in bytes: 12

你可以這樣做,或者你可以做一些更清潔的事情:

std::wcout << L"output: " << output.GetString() << std::endl;

這很容易,因為CString只是CStringT ,並且您還可以訪問CStringACStringW (您應該閱讀有關差異的文檔)。

CStringW myString = L"Hello World";
CString myConvertedString = myString;

您可以為此目的使用sprintf ,正如@l0pan 所提到的(但我使用了%ls而不是%ws ):

char output[256];
const WCHAR* wc = L"Hello World" ;
sprintf(output, "%ws", wc ); // did not work for me (Windows, C++ Builder)
sprintf(output, "%ls", wc ); // works

您可以使用std::wcsrtombs函數。

這是用於轉換的C++17重載集:

#include <iostream> // not required for the conversion function

// required for conversion
#include <cuchar>
#include <cwchar>
#include <stdexcept>
#include <string>
#include <string_view> // for std::wstring_view overload

std::string to_string(wchar_t const* wcstr){
    auto s = std::mbstate_t();
    auto const target_char_count = std::wcsrtombs(nullptr, &wcstr, 0, &s);
    if(target_char_count == static_cast<std::size_t>(-1)){
        throw std::logic_error("Illegal byte sequence");
    }

    // +1 because std::string adds a null terminator which isn't part of size
    auto str = std::string(target_char_count, '\0');
    std::wcsrtombs(str.data(), &wcstr, str.size() + 1, &s);
    return str;
}

std::string to_string(std::wstring const& wstr){
    return to_string(wstr.c_str());
}

std::string to_string(std::wstring_view const& view){
    // wstring because wstring_view is not required to be null-terminated!
    return to_string(std::wstring(view));
}

int main(){
    using namespace std::literals;

    std::cout
        << to_string(L"wchar_t const*") << "\n"
        << to_string(L"std::wstring"s) << "\n"
        << to_string(L"std::wstring_view"sv) << "\n";
}

如果你使用 Pre-C++17,你應該緊急更新你的編譯器! ;-)

如果這真的不可能,這里有一個 C++11 版本:

#include <iostream> // not required for the conversion function

// required for conversion
#include <cwchar>
#include <stdexcept>
#include <string>

std::string to_string(wchar_t const* wcstr){
    auto s = std::mbstate_t();
    auto const target_char_count = std::wcsrtombs(nullptr, &wcstr, 0, &s);
    if(target_char_count == static_cast<std::size_t>(-1)){
        throw std::logic_error("Illegal byte sequence");
    }

    // +1 because std::string adds a null terminator which isn't part of size
    auto str = std::string(target_char_count, '\0');
    std::wcsrtombs(const_cast<char*>(str.data()), &wcstr, str.size() + 1, &s);
    return str;
}

std::string to_string(std::wstring const& wstr){
    return to_string(wstr.c_str());
}

int main(){
    std::cout
        << to_string(L"wchar_t const*") << "\n"
        << to_string(std::wstring(L"std::wstring")) << "\n";
}

暫無
暫無

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

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