Преобразование между использованием std::wstring и std::строка


В то время как исследование способов преобразования взад и вперед между использованием std::wstring, которая и СТД::строка, я нашел этот разговор на форумах MSDN.

Там были две функции, которые для меня выглядели хорошо. В частности, эти:

std::wstring s2ws(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;
}

std::string ws2s(const std::wstring& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0); 
    char* buf = new char[len];
    WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, buf, len, 0, 0); 
    std::string r(buf);
    delete[] buf;
    return r;
}

Тем не менее, двойное распределение и нужно удалить буфер волнует (эффективность и безопасность исключений), поэтому я изменил их, чтобы быть такой:

std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
    std::wstring r(len, L'\0');
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, &r[0], len);
    return r;
}

std::string ws2s(const std::wstring& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0); 
    std::string r(len, '\0');
    WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, &r[0], len, 0, 0); 
    return r;
}

Модульное тестирование показывает, что это работает в хорошо контролируемых условиях, но будет ли это хорошо в порочный и непредсказуемый мир, который компьютер моего клиента?



74890
32
задан 29 января 2011 в 05:01 Источник Поделиться
Комментарии
5 ответов

Я бы, и есть, перестроить свой набор функций напоминают слепки:

std::wstring x;
std::string y = string_cast<std::string>(x);

Это может иметь много преимуществ позже, когда вы начинаете иметь дело с идеей, некоторые 3-й партии библиотеки, что строки должны выглядеть.

11
ответ дан 31 января 2011 в 06:01 Источник Поделиться

Единственное, в чем может быть проблема заключается в том, что он принимает строку в формате ANSI с использованием активной кодовой страницы (CP_ACP). Вы могли бы хотеть рассмотреть, используя определенную кодовую страницу или cp_utf8 используется, если он в UTF-8.

6
ответ дан 30 января 2011 в 04:01 Источник Поделиться

Я бы рекомендовал изменить это:

int len;
int slength = (int)s.length() + 1;
len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);

...на это:

int slength = (int)s.length() + 1;
int len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);

Немного более кратким, ленс области сокращается, и вы не неинициализированное переменной с плавающей вокруг (ок, только на одну линию) как ловушка для неосторожных.

4
ответ дан 2 февраля 2011 в 04:02 Источник Поделиться

Я не делаю никаких окон развития, поэтому я не могу комментировать , так и widechartomultibyte часть быть безопасным.

Одна вещь, я должен сказать, чтобы убедиться, что вы используете правильные типы для все. Например, строка.длина() возвращает объект std::строки::size_type (скорее всего, реализация, конструктор также берет с std::строки::size_type, но это не так важно). Он, наверное, никогда не укусит, но это что-то, чтобы быть осторожны, чтобы убедиться, что вы не имеете любые переполнения в другой код, вы можете писать.

2
ответ дан 29 января 2011 в 05:01 Источник Поделиться

Я только мельком посмотрел ваш код. Я не работал с std::строки много, но я много работал с API.

Предполагая, что вы получили все ваши длины и аргументы справа (иногда убедившись, что Терминатор и широкий против многобайтовых длины все право может быть сложно), я думаю, ты на правильном пути. Я думаю, что первой процедуры вы выложили излишне выделять дополнительный буфер. Он и не нужен.

0
ответ дан 29 января 2011 в 10:01 Источник Поделиться