Как конвертировать 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;
}

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

6 ответов


использовать 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.,


в вашем примере 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;
}

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


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

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

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


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

следуйте этому золотому правилу: "если вы используете голые указатели символов, вы делаете это неправильно. (За исключением тех случаев, когда это не так.)--7-->

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


Я сделал что-то подобное. Первые 2 нуля потому, что я не знаю, какие вещи типа ascii эта команда хочет от меня. Общее чувство, которое у меня было, - создать массив temp char. проходим в широкий массив char. бум. это работает. +1 гарантирует, что завершающий символ null находится в нужном месте.

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