如何将 const WCHAR \* 转换为 const char \*

新手上路,请多包涵
CString output ;
const WCHAR* wc = L"Hellow World" ;
if( wc != NULL )
{
     output.Append(wc);
}
printf( "output: %s\n",output.GetBuffer(0) );

原文由 jack 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 901
2 个回答

你也可以试试这个:

 #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;

编辑:关于回答评论的澄清:行 const char* c = b; 导致字符串的窄字符副本由 _bstr_t 实例创建和管理,该实例将在销毁时释放一次。运算符只返回一个指向该副本的指针。因此,无需复制此字符串。 Besides, in the question, CString::GetBuffer returns LPTSTR (ie TCHAR* ) and not LPCTSTR (ie const TCHAR* ) .

另一种选择是使用转换宏:

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

这种方法的问题是转换后的字符串的内存是在堆栈上分配的,因此字符串的长度是有限的。但是,这一系列转换宏允许您选择要用于转换的代码页,如果宽字符串包含非 ANSI 字符,则通常需要此代码页。

原文由 Zdeslav Vojkovic 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以使用 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";
}

原文由 Benjamin Buch 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题