3

我是 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”这样的任意东西?

4

6 回答 6

7

这是使用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);
}

这是一个演示。

于 2013-08-14T23:51:37.037 回答
6

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

解决方案“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);
于 2018-04-09T21:27:47.633 回答
4

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

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

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

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

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

于 2013-08-14T23:56:31.087 回答
0
wstring temp = L"";
for (auto c : DATA_DIR)
   temp.push_back(c);
于 2021-12-30T10:21:04.217 回答
0

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

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

于 2021-07-09T20:01:37.723 回答
-1

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

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);
于 2013-08-14T23:50:50.157 回答