std::wstring Преобразует первый символ случайным образом

У меня есть этот кусок кода:

const char * c = &(4:); //This pointer contains "JPG" string

//Wide char conversion
wchar_t *cc = new wchar_t[128];
MultiByteToWideChar(CP_ACP, 0, c, -1, cc, wcslen(cc));

Затем я объявляю переменную wstring:

wstring sFilter;
sFilter.append(L"Format: ");
sFilter.append(cc);
sFilter.push_back('\0');
sFilter.append(L"*.");
sFilter.append(cc);
sFilter.push_back('\0');
sFilter.push_back('\0');
const wchar_t * extensionFilter = sFilter.c_str();

Я формирую этот wchar_t, чтобы применить фильтр к GetOpenFileName функции из WinApi: ofn.lpstrFilter = extensionString;, которая является членом структуры.

Фильтр расширений случайным образом содержит: "3ormat: JPG" или ":ormat: JPG"...

Я не могу изменить проект на Unicode только потому, что среда IDE, над которой я работаю, не позволяет это делать. Поэтому мне нужно работать с этим.

введите здесь описание изображения


person ProtectedVoid    schedule 10.12.2015    source источник
comment
Каким должен быть &(4:)? Это недействительный код.   -  person Remy Lebeau    schedule 10.12.2015
comment
Это недопустимый код для стандарта С++, я работаю над IDE (CA Plex), которая передает параметры таким образом. IDE интерпретирует &(4:) и заменяет его допустимым значением.   -  person ProtectedVoid    schedule 10.12.2015


Ответы (1)


wchar_t *cc = new wchar_t[128];
MultiByteToWideChar(CP_ACP, 0, c, -1, cc, wcslen(cc));

new[] не заполняет память, которую выделяет. Вы вызываете wcslen() для буфера, который не обязательно завершается нулем. И даже если бы это было так, ноль был бы впереди буфера, поэтому wcslen() вернул бы 0. Вам нужно передать фактическую длину выделенного буфера:

MultiByteToWideChar(CP_ACP, 0, c, -1, cc, 128);

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

Вам не нужно менять весь проект. В любом случае это влияет только на объявления на основе TCHAR. Поскольку ваши входные данные - Ansi, вы можете просто вызвать GetOpenFileNameA() напрямую и не беспокоиться о том, чтобы сначала преобразовать ваши входные данные в Unicode:

const char * c = ...; //This pointer contains "JPG" string

string sFilter;
sFilter.append("Format: ");
sFilter.append(c);
sFilter.push_back('\0');
sFilter.append("*.");
sFilter.append(c);
sFilter.push_back('\0');
sFilter.push_back('\0');
const char * extensionFilter = sFilter.c_str();

OPENFILENAMEA ofn;
...
ofn.lpstrFilter = extensionFilter;
...
GetOpenFileNameA(&ofn);
person Remy Lebeau    schedule 10.12.2015
comment
Исправил эту часть, но проблема не решена. Спасибо. - person ProtectedVoid; 10.12.2015
comment
Пожалуйста, проверьте этот пост, в котором у меня были проблемы с ANSI, и решение использовало Unicode: stackoverflow.com/questions/34201213/ - person ProtectedVoid; 10.12.2015
comment
Кажется, вы не совсем понимаете, как на самом деле работают строки с завершающим нулем, особенно в отношении std::(w)string. Вы продолжаете злоупотреблять ими, вот почему вы попадаете в такие неприятности. Ваша проблема в другом вопросе вообще НИЧЕГО не имела отношения к Ansi vs Unicode (Unicode был предложен, потому что это то, что вы должны использовать, но это отдельная проблема). Вы просто неправильно управляли строковыми данными с самого начала. - person Remy Lebeau; 10.12.2015