C ++ Преобразование строки (или char *) в wstring (или wchar_t *)

string s = "おはよう"; wstring ws = FUNCTION(s, ws); 

Как назначить содержимое s на ws?

Поиск Google и использование некоторых методов, но они не могут назначить точный контент. Содержимое искажено.

Предполагая, что входная строка в вашем примере (お は よ う) является кодировкой UTF-8 (чего нет, по ее мнению, но предположим, что это ради этого объяснения :-)) представление строки Unicode вашего интереса, то ваша проблема может быть полностью решена с помощью стандартной библиотеки (только C ++ 11 и новее).

Версия TL: DR:

 #include  #include  #include  std::wstring_convert> converter; std::string narrow = converter.to_bytes(wide_utf16_source_string); std::wstring wide = converter.from_bytes(narrow_utf8_source_string); 

Более длинный онлайн-компилируемый и исполняемый пример:

(Все они показывают один и тот же пример. Всего лишь для избыточности …)

Примечание (старый) :

Как указано в комментариях и объяснено в https://stackoverflow.com/a/17106065/6345, есть случаи, когда использование стандартной библиотеки для преобразования между UTF-8 и UTF-16 может привести к неожиданным различиям в результатах на разных платформах , Для лучшего преобразования рассмотрите std::codecvt_utf8 как описано на http://en.cppreference.com/w/cpp/locale/codecvt_utf8

Примечание (новое) :

Поскольку заголовок codecvt устарел на C ++ 17, некоторые проблемы с решением, представленным в этом ответе, были подняты. Тем не менее, комитет по стандартам C ++ добавил важное заявление в http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html, в котором говорится:

этот компонент библиотеки должен быть удален в приложение D вместе с ним, пока стандартная стандартная замена не будет заменена.

Поэтому в обозримом будущем решение codecvt в этом ответе безопасно и переносимо.

 int StringToWString(std::wstring &ws, const std::string &s) { std::wstring wsTmp(s.begin(), s.end()); ws = wsTmp; return 0; } 

Ваш вопрос не указан. Строго говоря, этот пример является синтаксической ошибкой. Однако std::mbstowcs – это, вероятно, то, что вы ищете.

Это функция C-библиотеки и работает на буферах, но вот простую в использовании идиому, любезно предоставленную TBohne (ранее Mooing Duck):

 std::wstring ws(s.size(), L' '); // Overestimate number of code points. ws.resize(std::mbstowcs(&ws[0], s.c_str(), s.size())); // Shrink to fit. 

Только для Windows API, реализация до C ++ 11, если кому-то это необходимо:

 #include  #include  #include  using std::runtime_error; using std::string; using std::vector; using std::wstring; wstring utf8toUtf16(const string & str) { if (str.empty()) return wstring(); size_t charsNeeded = ::MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0); if (charsNeeded == 0) throw runtime_error("Failed converting UTF-8 string to UTF-16"); vector buffer(charsNeeded); int charsConverted = ::MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &buffer[0], buffer.size()); if (charsConverted == 0) throw runtime_error("Failed converting UTF-8 string to UTF-16"); return wstring(&buffer[0], charsConverted); } 

Если вы используете Windows / Visual Studio и вам нужно преобразовать строку в wstring, вы можете использовать:

 #include  #include  ... string s = "some string"; CA2W ca2w(s.c_str()); wstring w = ca2w; printf("%s = %ls", s.c_str(), w.c_str()); 

Такая же процедура для преобразования wstring в строку (иногда вам нужно указать кодовую страницу ):

 #include  #include  ... wstring w = L"some wstring"; CW2A cw2a(w.c_str()); string s = cw2a; printf("%s = %ls", s.c_str(), w.c_str()); 

Вы можете указать кодовую страницу и даже UTF8 (это довольно хорошо при работе с JNI / Java ).

 CA2W ca2w(str, CP_UTF8); 

Если вы хотите узнать больше о кодовых страницах, есть интересная статья о Joel on Software: The Absolute Minimum. Каждый разработчик программного обеспечения абсолютно уверен, должен знать об Unicode и наборах символов .

Эти macros CA2W (преобразовать Ansi в Wide = unicode) являются частью макросов преобразования строк ATL и MFC , включая образцы.

Иногда вам нужно отключить предупреждение о безопасности # 4995 ‘, я не знаю другого обходного пути (для меня это происходит, когда я скомпилирован для WindowsXp в VS2012).

 #pragma warning(push) #pragma warning(disable: 4995) #include  #include  #pragma warning(pop) 

Редактировать: Ну, согласно этой статье, статья Джоэла выглядит так: «в то время как развлекательная, она довольно освещена на реальных технических деталях». Статья: Что каждый программист абсолютно, положительно должен знать о кодировании и наборах символов для работы с текстом .

От char* до wstring :

 char* str = "hello worlddd"; wstring wstr (str, str+strlen(str)); 

От string до wstring :

 string str = "hello worlddd"; wstring wstr (str.begin(), str.end()); 

Обратите внимание, что это работает только хорошо, если преобразованная строка содержит только символы ASCII.

Вот способ объединения string , wstring и смешанных строковых констант в wstring . Используйте class wstringstream .

 #include  std::string narrow = "narrow"; std::wstring wide = "wide"; std::wstringstream cls; cls << " abc " << narrow.c_str() << L" def " << wide.c_str(); std::wstring total= cls.str(); 

используя Boost.Locale:

 ws = boost::locale::conv::utf_to_utf(s); 

Этот вариант – мой любимый в реальной жизни. Он преобразует вход, если он действителен UTF-8, в соответствующую wstring . Если вход поврежден, wstring построен из одного байта. Это очень полезно, если вы не можете быть уверены в качестве ваших входных данных.

 std::wstring convert(const std::string& input) { try { std::wstring_convert> converter; return converter.from_bytes(input); } catch(std::range_error& e) { size_t length = input.length(); std::wstring result; result.reserve(length); for(size_t i = 0; i < length; i++) { result.push_back(input[i] & 0xFF); } return result; } } 

Метод s2ws работает хорошо. Надежда помогает.

 std::wstring s2ws(const std::string& s) { std::string curLocale = setlocale(LC_ALL, ""); const char* _Source = s.c_str(); size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1; wchar_t *_Dest = new wchar_t[_Dsize]; wmemset(_Dest, 0, _Dsize); mbstowcs(_Dest,_Source,_Dsize); std::wstring result = _Dest; delete []_Dest; setlocale(LC_ALL, curLocale.c_str()); return result; } 

Основываясь на моем собственном тестировании (на windowsх 8, vs2010), mbstowcs может фактически повредить исходную строку, она работает только с кодовой страницей ANSI. Если MultiByteToWideChar / WideCharToMultiByte также может вызвать повреждение строки, но они имеют тенденцию заменять символы, которые они не знают с помощью?? вопросительные знаки, но mbstowcs имеет тенденцию останавливаться, когда он встречает неизвестный символ и вырезает строку в этой самой точке. (Я тестировал вьетнамских персонажей на финских windowsх).

Поэтому предпочитайте функцию Multi * -windows api над аналоговыми функциями ansi C.

Также я заметил, что самый короткий способ кодирования строки из одной кодовой страницы в другую не использует вызовы функций MultiByteToWideChar / WideCharToMultiByte api, но их аналоговые macros ATL: W2A / A2W.

Таким образом, аналоговая функция, упомянутая выше, будет звучать так:

 wstring utf8toUtf16(const string & str) { USES_CONVERSION; _acp = CP_UTF8; return A2W( str.c_str() ); } 

_acp объявляется в макросе USES_CONVERSION.

Или также функцию, которую я часто пропускаю при выполнении старого преобразования данных в новый:

 string ansi2utf8( const string& s ) { USES_CONVERSION; _acp = CP_ACP; wchar_t* pw = A2W( s.c_str() ); _acp = CP_UTF8; return W2A( pw ); } 

Но обратите внимание, что использование этих макросов сильно стека – не использовать для циклов или рекурсивных циклов для одной и той же функции – после использования макроса W2A или A2W – лучше возвращать ASAP, поэтому стек будет освобожден от временного преобразования.

string s = "おはよう"; является ошибкой.

Вы должны использовать wstring напрямую:

 wstring ws = L"おはよう"; 

используйте этот код для преобразования строки в wstring

 std::wstring string2wString(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; } int main(){ std::wstring str="your string"; std::wstring wStr=string2wString(str); return 0; } 
  • Почему этот код использует случайные строки для печати «hello world»?
  • .NET Формат строки с фиксированными пространствами
  • Поиск строки Java, игнорирующий акценты
  • В Java, как я могу анализировать XML как строку вместо файла?
  • Равноправие строк и равенство места
  • Статическая константная строка C ++ (член classа)
  • Регулярное выражение для поиска URL-адресов внутри строки
  • Почему строки нельзя изменять в Java и .NET?
  • Excel VBA: диапазон до строкового массива в 1 шаг
  • Сбор мусора струнных литералов
  • преобразовать строку в массив чисел в matlab
  • Давайте будем гением компьютера.