Как преобразовать char * в wchar_t *?
Я пробовал реализовать такую функцию, но, к сожалению, она не работает:
const wchar_t *GetWC(const char *c)
{
const size_t cSize = strlen(c)+1;
wchar_t wc[cSize];
mbstowcs (wc, c, cSize);
return wc;
}
Моя главная цель здесь - уметь интегрировать обычные строки char в приложении Unicode. Любой совет, который вы, ребята, можете предложить, очень ценится.
Ответы
Ответ 1
Используйте std::wstring
вместо массива переменной длины C99. Текущий стандарт гарантирует непрерывный буфер для std::basic_string
. Например.
std::wstring wc( cSize, L'#' );
mbstowcs( &wc[0], c, cSize );
С++ не поддерживает массивы переменной длины C99, поэтому, если вы скомпилировали свой код как чистый С++, он даже не компилируется.
С этим изменением возвращаемый тип функции также должен быть std::wstring
.
Не забудьте установить соответствующий язык в main
.
Например, setlocale( LC_ALL, "" )
.
Приветствия и hth.,
Ответ 2
В вашем примере wc
- это локальная переменная, которая будет освобождена при завершении вызова функции. Это помещает вас в область поведения undefined.
Простое исправление:
const wchar_t *GetWC(const char *c)
{
const size_t cSize = strlen(c)+1;
wchar_t* wc = new wchar_t[cSize];
mbstowcs (wc, c, cSize);
return wc;
}
Обратите внимание, что вызывающий код должен будет освободить эту память, иначе у вас будет утечка памяти.
Ответ 3
const char* text_char = "example of mbstowcs";
size_t length = strlen(text_char );
Пример использования "mbstowcs"
std::wstring text_wchar(length, L'#');
//#pragma warning (disable : 4996)
// Or add to the preprocessor: _CRT_SECURE_NO_WARNINGS
mbstowcs(&text_wchar[0], text_char , length);
Пример использования "mbstowcs_s"
Microsoft предлагает использовать "mbstowcs_s" вместо "mbstowcs".
Ссылки:
Пример Mbstowcs
mbstowcs_s, _mbstowcs_s_l
wchar_t text_wchar[30];
mbstowcs_s(&length, text_wchar, text_char, length);
Ответ 4
Вы возвращаете адрес локальной переменной, выделенной в стеке. Когда ваша функция вернется, хранилище для всех локальных переменных (например, wc
) будет освобождено и будет немедленно перезаписано чем-то другим.
Чтобы исправить это, вы можете передать размер буфера в GetWC
, но тогда у вас есть почти такой же интерфейс, как mbstowcs
. Или вы можете выделить новый буфер внутри GetWC
и вернуть указатель на него, оставив его вызывающему абоненту для освобождения буфера.
Ответ 5
Ваша проблема не имеет ничего общего с кодировками, это простой вопрос понимания базового С++. Вы возвращаете указатель на локальную переменную из вашей функции, которая к тому времени, когда кто-либо сможет ее использовать, выйдет за рамки, создав при этом поведение undefined (т.е. Ошибка программирования).
Следуйте этому Золотому правилу: "Если вы используете голые указатели char, вы делаете это неправильно. (За исключением случаев, когда вы этого не делаете.)"
Я ранее некорректный код для преобразования и передачи ввода и вывода в объектах С++ std::string
и std::wstring
.
Ответ 6
Я сделал что-то вроде этого. Первые 2 нули - это потому, что я не знаю, какие вещи типа ascii эта команда хочет от меня. Общее чувство, которое у меня было, - создать массив temp char. перейдите в широкий массив char. бум. оно работает. +1 гарантирует, что нулевой завершающий символ находится в нужном месте.
char tempFilePath[MAX_PATH] = "I want to convert this to wide chars";
int len = strlen(tempFilePath);
// Converts the path to wide characters
int needed = MultiByteToWideChar(0, 0, tempFilePath, len + 1, strDestPath, len + 1);
Ответ 7
От @Cheers и hth. - Ответ Alf, я понял, что функция std:: wstring.data() возвращает wchar *.
Таким образом, код просто:
const wchar_t *GetWC(const char *c){
const size_t cSize = strlen(c) + 1;
std::wstring wc( cSize, L'#' );
mbstowcs( &wc[0], c, cSize );
return wc.data();
}
Счастливое кодирование,