Подтвердить что ты не робот

Как преобразовать 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. Любой совет, который вы, ребята, можете предложить, очень ценится.

4b9b3361

Ответ 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();
     }

Счастливое кодирование,