преобразование узкой строки в широкую - PullRequest
6 голосов
/ 14 июля 2011

Как я могу преобразовать узкий string в широкий string?

Я пробовал этот метод:

string myName;
getline( cin , myName );
wstring printerName( L(myName) );  // error C3861: 'L': identifier not found
wchar_t* WprinterName = printerName.c_str(); // error C2440: 'initializing' : cannot convert from 'const wchar_t *' to 'wchar_t *'

Но я получаю ошибки, перечисленные выше.

Почему я получаю эти ошибки? Как я могу их исправить?

Есть ли другой способ прямого преобразования строки narrow в строку wide?

Ответы [ 9 ]

7 голосов
/ 14 июля 2011

Вы должны сделать это:

inline std::wstring convert( const std::string& as )
{
            // deal with trivial case of empty string
    if( as.empty() )    return std::wstring();

            // determine required length of new string
    size_t reqLength = ::MultiByteToWideChar( CP_UTF8, 0, as.c_str(), (int)as.length(), 0, 0 );

            // construct new string of required length
    std::wstring ret( reqLength, L'\0' );

            // convert old string to new string
    ::MultiByteToWideChar( CP_UTF8, 0, as.c_str(), (int)as.length(), &ret[0], (int)ret.length() );

            // return new string ( compiler should optimize this away )
    return ret;
}

Ожидается, что std :: string будет UTF-8 (CP_UTF8), когда у вас есть другая кодировка, замените кодовую страницу.

Другой способ может быть:

inline std::wstring convert( const std::string& as )
{
    wchar_t* buf = new wchar_t[as.size() * 2 + 2];
    swprintf( buf, L"%S", as.c_str() );
    std::wstring rval = buf;
    delete[] buf;
    return rval;
}
6 голосов
/ 14 июля 2011

Если источник в кодировке ASCII, вы можете просто сделать это:

wstring printerName;
printerName.assign( myName.begin(), myName.end() );
3 голосов
/ 13 мая 2014

Вот две функции, которые можно использовать: mbstowcs_s и wcstombs_s.

mbstowcs_s: преобразует последовательность многобайтовых символов в соответствующую последовательность широких символов. wcstombs_s: преобразует последовательность широких символов в соответствующую последовательность многобайтовых символов.

errno_t wcstombs_s(
   size_t *pReturnValue,
   char *mbstr,
   size_t sizeInBytes,
   const wchar_t *wcstr,
   size_t count 
);

errno_t mbstowcs_s(
   size_t *pReturnValue,
   wchar_t *wcstr,
   size_t sizeInWords,
   const char *mbstr,
   size_t count 

);

См. http://msdn.microsoft.com/en-us/library/eyktyxsx.aspx и http://msdn.microsoft.com/en-us/library/s7wzt4be.aspx.

3 голосов
/ 24 января 2014

ATL (не экспресс-выпуски Visual Studio) имеет несколько полезных типов классов, которые могут преобразовывать строки просто. Вы можете использовать конструктор напрямую, если вам не нужно удерживать строку.

#include <atlbase.h>

std::wstring wideString(L"My wide string");
std::string narrowString("My not-so-wide string");

ATL::CW2A narrow(wideString.c_str()); // narrow is a narrow string
ATL::CA2W wide(asciiString.c_str()); // wide is a wide string
3 голосов
/ 14 июля 2011

Я нашел это , пока гуглил проблему.Я вставил код для справки.Автор этого поста - Пол Маккензи.

std::string str = "Hello";
std::wstring str2(str.length(), L' '); // Make room for characters

// Copy string to wstring.
std::copy(str.begin(), str.end(), str2.begin());
1 голос
/ 27 сентября 2016

Первоначальный вопрос этой темы был: «Как я могу преобразовать узкую строку в широкую строку?»

Однако из приведенного в вопросе примера кода, похоже, преобразование не требуется. Скорее, есть ошибка компилятора из-за того, что новые компиляторы устарели, что раньше было нормально. Вот что я думаю:

    // wchar_t* wstr = L"A wide string";     // Error: cannot convert from 'const wchar_t *' to 'wchar_t *'

wchar_t const* wstr = L"A wide string";             // okay
const wchar_t* wstr_equivalent = L"A wide string";  // also okay

Кажется, что c_str () обрабатывается так же, как и литерал, и считается константой (const). Вы могли бы использовать бросок. Но предпочтительнее добавить конст.

Лучший ответ, который я видел для преобразования между широкими и узкими строками, это использовать std :: wstringstream. И это один из ответов, данных C ++ Преобразование строки (или char *) в wstring (или wchar_t *)

Вы можете преобразовывать практически все что угодно в строки и из широких строк, используя stringstream и wstringstream.

1 голос
/ 14 июля 2011

Windows API предоставляет процедуры для этого: WideCharToMultiByte () и MultiByteToWideChar ().Тем не менее, они являются болью в использовании.Каждое преобразование требует двух обращений к подпрограммам, и вы должны следить за выделением / освобождением памяти и проверкой правильности завершения строк.Вам нужна оболочка!

У меня есть удобная оболочка C ++ в моем блоге, здесь , которую вы можете использовать.

0 голосов
/ 09 февраля 2018

Использование mbtowc ():

string myName;
wchar_t wstr[BUFFER_SIZE];

getline( cin , myName );
mbtowc(wstr, myName, BUFFER_SIZE);
0 голосов
/ 07 октября 2016

В этой статье , опубликованной в сентябрьском выпуске журнала MSDN Magazine 2016, подробно рассматривается преобразование с использованием API-интерфейсов Win32.

Обратите внимание, что использование MultiByteToWideChar() означает намного быстрее , чемиспользуя std :: stuff в Windows.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...