【问题标题】:How do I convert a string to a wstring using the value of the string?如何使用字符串的值将字符串转换为 wstring?
【发布时间】:2013-08-17 03:18:06
【问题描述】:

我是 C++ 新手,遇到了这个问题。我有一个名为 DATA_DIR 的字符串,我需要将其格式化为 wstring。

string str = DATA_DIR;
std::wstring temp(L"%s",str); 

Visual Studio 告诉我没有与参数列表匹配的构造函数实例。很明显,我做错了什么。

我在网上找到了这个例子

std::wstring someText( L"hello world!" );

这显然有效(没有编译错误)。我的问题是,如何将存储在 DATA_DIR 中的字符串值放入 wstring 构造函数中,而不是像“hello world”这样的任意东西?

【问题讨论】:

  • 查看 utf8everywhere.org 并考虑使用该页面上提供的 boost::nowide 库将字符串转换为 wstring 并返回。让生活更轻松:)
  • string中的文字编码是什么?通常是 ISO/IEC 8859-1(许多错误地称为“ASCII”)或 UTF-8。
  • 请在下面查看我的编辑。我的原始代码有一个很大的错误。

标签: c++ string wstring


【解决方案1】:

这是一个使用wcstombs(更新)的实现:

#include <iostream>
#include <cstdlib>
#include <string>
 
std::string wstring_from_bytes(std::wstring const& wstr)
{
    std::size_t size = sizeof(wstr.c_str());
    char *str = new char[size];
    std::string temp;
 
    std::wcstombs(str, wstr.c_str(), size);

    temp = str;
    delete[] str;
 
    return temp;
}
 
int main()
{
    std::wstring wstr = L"abcd";
    std::string str = wstring_from_bytes(wstr);
}

Here is a demo.

【讨论】:

    【解决方案2】:

    这是指投票最多的答案,但我没有足够的“声誉”来直接评论答案。

    解决方案“wstring_from_bytes”中的函数名称暗示它正在做原始发布者想要的,即在给定字符串的情况下获取 wstring,但该函数实际上与原始发布者要求的相反,并且更准确地说是“bytes_from_wstring”。

    要从字符串转换为 wstring,wstring_from_bytes 函数应该使用 mbstowcs 而不是 wcstombs

    #define _CRT_SECURE_NO_WARNINGS
    
    #include <iostream>
    #include <cstdlib>
    #include <string>
    
    std::wstring wstring_from_bytes(std::string const& str)
    {
        size_t requiredSize = 0;
        std::wstring answer;
        wchar_t *pWTempString = NULL;
    
        /*
        * Call the conversion function without the output buffer to get the required size
        *  - Add one to leave room for the NULL terminator
        */
        requiredSize = mbstowcs(NULL, str.c_str(), 0) + 1;
    
        /* Allocate the output string (Add one to leave room for the NULL terminator) */  
        pWTempString = (wchar_t *)malloc( requiredSize * sizeof( wchar_t ));  
        if (pWTempString == NULL)  
        {  
            printf("Memory allocation failure.\n");  
        }
        else
        {
            // Call the conversion function with the output buffer
            size_t size = mbstowcs( pWTempString, str.c_str(), requiredSize);
            if (size == (size_t) (-1))  
            {  
                printf("Couldn't convert string\n");  
            }
            else
            {
                answer = pWTempString;
            }
        }
    
    
        if (pWTempString != NULL)
        {
            delete[] pWTempString;
        }
    
        return answer;
    }
    
    int main()
    {
       std::string str = "abcd";
       std::wstring wstr = wstring_from_bytes(str);
    }
    

    无论如何,这在标准库的新版本(C++ 11 和更高版本)中更容易完成

    #include <locale>
    #include <codecvt>
    #include <string>
    
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    
    std::wstring wide = converter.from_bytes(narrow_utf8_source_string);
    

    【讨论】:

    • 答案的 C++11 部分对我有用。谢谢!
    【解决方案3】:

    printf 样式的格式说明符不是 C++ 库的一部分,不能用于构造 string

    如果string 可能只包含单字节字符,那么范围构造函数就足够了。

    std::string narrower( "hello" );
    std::wstring wider( narrower.begin(), narrower.end() );
    

    问题是我们通常在适用宽字符时使用wstring(因此是w),它们在std::string中由多字节序列表示。这样做会导致多字节序列的每个字节转换为不正确的宽字符序列。

    此外,转换多字节序列需要知道其编码。此信息未被std::stringstd::wstring 封装。 C++11 允许您使用std::wstring_convert 指定编码和翻译,但我不确定它的支持范围有多广。请参阅 0x.... 的出色答案。

    【讨论】:

      【解决方案4】:

      C++11 及以上提到的转换器已弃用 C++17 中的这种特定转换,并建议使用 MultiByteToWideChar 函数。

      编译器错误 (c4996) 提到定义 _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING。

      【讨论】:

      • 这如何回答这个问题?我认为作为相关答案下的评论会更好。
      【解决方案5】:
      wstring temp = L"";
      for (auto c : DATA_DIR)
         temp.push_back(c);
      

      【讨论】:

        【解决方案6】:

        我找到了这个功能。找不到任何预定义的方法来执行此操作。

        std::wstring s2ws(const std::string& s)
        {
            int len;
            int slength = (int)s.length() + 1;
            len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
            wchar_t* buf = new wchar_t[len];
            MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
            std::wstring r(buf);
            delete[] buf;
            return r;
        }
        
        std::wstring stemp = s2ws(myString);
        

        【讨论】:

        • 这不是使用标准库。它看起来像 Win32。
        • 是的,它没有使用标准库。 Asker 正在使用 Visual Studio。如果他正在使用 WINAPI 会有所帮助。
        • CP_ACP 到底是做什么的?它似乎指定了系统定义的非多字节编码。这个 API 使得编写可移植性非常困难。
        • CP_ACP是定义MultiByteToWideChar进行转换时的codepage。 CP_ACP 将其定义为 ANSI 代码页。
        • 而且“ANSI codepage”是一个定义不明确的概念,很可能不是他想要的。
        猜你喜欢
        • 1970-01-01
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-05
        • 2011-05-20
        • 1970-01-01
        相关资源
        最近更新 更多