C ++ Преобразование строки (или char *) в wstring (или wchar_t *)
string s = "おはよう"; wstring ws = FUNCTION(s, ws);
Как назначить содержимое s на ws?
Поиск Google и использование некоторых методов, но они не могут назначить точный контент. Содержимое искажено.
- Помещение символа в строку java для каждого символа N
- Получить OutputStream в строку
- Форматирование строки в столбцы
- Обратить каждое отдельное слово строки «Hello World» с помощью Java
- Проверьте, если символы в строке в R
- Пул строк и постоянный пул
- Java: Является ли assertEquals (String, String) надежным?
- Как преобразовать std :: string в нижний регистр?
- Сравнение строки с пустой строкой (Java)
- Строка подключения с относительным путем к файлу базы данных
- В Java, как проверить, содержит ли строка подстроку (игнорируя регистр)?
- Сколько памяти использует строка в Java 8?
- Максимальная длина длины строки содержимого (8192) была превышена при чтении XML-данных
Предполагая, что входная строка в вашем примере (お は よ う) является кодировкой 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; }