Как конвертировать char * в wchar_t *? - PullRequest
48 голосов
/ 07 ноября 2011

Я пытался реализовать такую ​​функцию, но, к сожалению, она не работает:

const wchar_t *GetWC(const char *c)
{
    const size_t cSize = strlen(c)+1;
    wchar_t wc[cSize];
    mbstowcs (wc, c, cSize);

    return wc;
}

Моя главная цель здесь - иметь возможность интегрировать обычные строки символов в приложение Unicode. Любые советы, которые вы, ребята, можете дать, очень ценятся.

Ответы [ 6 ]

36 голосов
/ 07 ноября 2011

В вашем примере wc - это локальная переменная, которая будет освобождена после завершения вызова функции. Это помещает вас в неопределенную область поведения.

Простое исправление таково:

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

Обратите внимание, что вызывающему коду затем придется освободить эту память, иначе у вас будет утечка памяти.

31 голосов
/ 07 ноября 2011

Используйте std::wstring вместо массива переменной длины C99.Текущий стандарт гарантирует непрерывный буфер для std::basic_string.Например,

std::wstring wc( cSize, L'#' );
mbstowcs( &wc[0], c, cSize );

C ++ не поддерживает массивы переменной длины C99, и поэтому, если вы скомпилировали свой код как чистый C ++, он даже не скомпилируется.также должно быть std::wstring.

Не забудьте установить соответствующий языковой стандарт в main.

Например, setlocale( LC_ALL, "" ).

Приветствия и hth.,

4 голосов
/ 07 сентября 2015
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);
2 голосов
/ 07 ноября 2011

Вы возвращаете адрес локальной переменной, размещенной в стеке.Когда ваша функция возвращается, хранилище для всех локальных переменных (таких как wc) освобождается и может быть немедленно перезаписано чем-то другим.

Чтобы исправить это, вы можете передать размер буфера вGetWC, но тогда у вас почти такой же интерфейс, как и у mbstowcs.Или вы можете выделить новый буфер внутри GetWC и вернуть на него указатель, оставив его на усмотрение вызывающей стороны для освобождения буфера.

1 голос
/ 10 февраля 2013

Я сделал что-то подобное. Первые 2 нуля объясняются тем, что я не знаю, какие вещи типа ascii эта команда хочет от меня Общее чувство, которое у меня было, было создать массив временных символов. передать широкий массив символов. бум. оно работает. +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);
1 голос
/ 07 ноября 2011

Ваша проблема не имеет ничего общего с кодировками, это простой вопрос понимания базового C ++.Вы возвращаете указатель на локальную переменную из вашей функции, которая выйдет из области действия к тому времени, когда кто-либо сможет ее использовать, создавая таким образом неопределенное поведение (т.е. ошибка программирования).

Следуйте этому золотому правилу: «Если вы используете голые указатели на символы, вы делаете это неправильно. (За исключением случаев, когда это не так.)»

У меня ранее опубликовано некоторый код для преобразования и передачи ввода и вывода в объектах C ++ std::string и std::wstring.

...