Есть ли какая-либо проблема?
Есть несколько проблем:
CString
- это шаблонная специализация CStringT . В зависимости от BaseType , описывающего тип символа, существует две конкретные специализации: CStringA
(с использованием char
) и CStringW
(с использованием wchar_t
).
- Хотя
wchar_t
в Windows повсеместно используется для хранения кодированных единиц UTF-16, использование char
неоднозначно. Последний обычно хранит символы в кодировке ANSI, но также может хранить ASCII, UTF-8 или даже двоичные данные.
- Мы не знаем кодировку символов (или даже тип символов)
CString
(которая управляется с помощью символа препроцессора _UNICODE
), что делает вопрос неоднозначным. Мы также не знаем желаемую кодировку символов std::string
.
- Преобразование между Юникодом и ANSI по своей природе сопряжено с потерями: кодировка ANSI может представлять только подмножество набора символов Юникода.
Для решения этих проблем я собираюсь предположить, что wchar_t
будет хранить кодированные единицы UTF-16, а char
будет содержать октетные последовательности UTF-8. Это единственный разумный выбор, который вы можете сделать, чтобы гарантировать, что строки источника и назначения сохраняют одну и ту же информацию, не ограничивая решение подмножеством доменов источника или назначения.
Следующие реализации преобразуют между CStringA
/ CStringW
и std::wstring
/ std::string
отображением из UTF-8 в UTF-16 и наоборот:
#include <string>
#include <atlconv.h>
std::string to_utf8(CStringW const& src_utf16)
{
return { CW2A(src_utf16.GetString(), CP_UTF8).m_psz };
}
std::wstring to_utf16(CStringA const& src_utf8)
{
return { CA2W(src_utf8.GetString(), CP_UTF8).m_psz };
}
Оставшиеся две функции создают строковые объекты C ++ из строк MFC, оставляя кодировку без изменений. Обратите внимание, что хотя предыдущие функции не могут работать со встроенными символами NUL, эти функции защищены от этого.
#include <string>
#include <atlconv.h>
std::string to_std_string(CStringA const& src)
{
return { src.GetString(), src.GetString() + src.GetLength() };
}
std::wstring to_std_wstring(CStringW const& src)
{
return { src.GetString(), src.GetString() + src.GetLength() };
}