C++ не может преобразовать строку в wstring

Я хотел бы преобразовать строковую переменную в wstring из-за некоторых немецких символов, которые вызывают проблемы при выполнении подстроки над переменной. Начальная позиция искажается, если перед ней присутствуют какие-либо из этих специальных символов. (Например: для "ä" size() возвращает 2 вместо 1)

Я знаю, что работает следующее преобразование:

wstring ws = L"ä";

Поскольку я пытаюсь преобразовать переменную, я хотел бы знать, есть ли альтернативный способ для нее, такой как

wstring wstr = L"%s"+str //this is syntaxically wrong, but wanted sth alike

Кроме того, я уже пробовал следующий пример для преобразования строки в wstring:

string foo("ä"); 
wstring_convert<codecvt_utf8<wchar_t>> converter;
wstring wfoo = converter.from_bytes(foo.data());
cout << foo.size() << endl;
cout << wfoo.size() << endl;

но я получаю ошибки как

‘wstring_convert’ was not declared in this scope

Я использую Ubuntu 14.04 и мой main.cpp скомпилирован с помощью cmake. Спасибо за вашу помощь!

3 ответа

Решение

Решение от "хахакубиле" сработало у меня:

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;
}

Но возвращаемое значение не на 100% правильно:

string s = "101446012MaßnStörfall   PAt  #Maßnahme Störfall                      00810000100121000102000020100000000000000";
wstring ws2 = s2ws(s);
cout << ws2.size() << endl; // returns 110 which is correct
wcout << ws2.substr(29,40) << endl; // returns #Ma�nahme St�rfall with symbols

Мне интересно, почему он заменил немецкие символы с символами.

Еще раз спасибо!

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

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

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

#include <AtlBase.h>
#include <atlconv.h>
...
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);

Если вы хотите узнать больше о кодовых страницах, то есть интересная статья о Джоэле о программном обеспечении: Абсолютный минимум, который должен знать каждый разработчик программного обеспечения. Об Unicode и наборах символов необходимо знать абсолютно.

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

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

#pragma warning(push)
#pragma warning(disable: 4995)
#include <AtlBase.h>
#include <atlconv.h>
#pragma warning(pop)

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

Главное, что

string foo("ä")

Это уже ошибка. Начните отсюда и прочитайте все ответы. И будьте осторожны, один очень ошибается:)

Другие вопросы по тегам