2008-10-19 6 views
48

Я прочитал документацию на WideCharToMultiByte, но я застрял на этот параметр:Как вы правильно использовать WideCharToMultiByte

lpMultiByteStr 
[out] Pointer to a buffer that receives the converted string. 

Я не совсем уверен, как правильно инициализировать переменную и кормить его в функция

+15

Есть ли причина, по которой вы, кажется, задаете вопросы, но не принимаете ответы? Обычно на этих сайтах хорошая практика вознаграждать хорошие ответы с обратной связью в знак признания того времени, когда люди вкладывают средства в ответ на ваш вопрос. У вас есть несколько очень хороших ответов ниже ... (nudge) – 2012-10-07 05:45:39

ответ

16

Вы используете параметр lpMultiByteStr [out], создав новый массив символов. Затем вы передаете этот массив символов, чтобы заполнить его. Вам нужно только инициализировать длину строки + 1, чтобы после преобразования вы могли иметь строку с нулевым завершением.

Вот несколько полезных вспомогательных функций для вас, они показывают использование всех параметров.

#include <string> 

std::string wstrtostr(const std::wstring &wstr) 
{ 
    // Convert a Unicode string to an ASCII string 
    std::string strTo; 
    char *szTo = new char[wstr.length() + 1]; 
    szTo[wstr.size()] = '\0'; 
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, szTo, (int)wstr.length(), NULL, NULL); 
    strTo = szTo; 
    delete[] szTo; 
    return strTo; 
} 

std::wstring strtowstr(const std::string &str) 
{ 
    // Convert an ASCII string to a Unicode String 
    std::wstring wstrTo; 
    wchar_t *wszTo = new wchar_t[str.length() + 1]; 
    wszTo[str.size()] = L'\0'; 
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wszTo, (int)str.length()); 
    wstrTo = wszTo; 
    delete[] wszTo; 
    return wstrTo; 
} 

-

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

Таким образом, вы можете понять это лучше:

//pX is an out parameter, it fills your variable with 10. 
void fillXWith10(int *pX) 
{ 
    *pX = 10; 
} 

int main(int argc, char ** argv) 
{ 
    int X; 
    fillXWith10(&X); 
    return 0; 
} 
+4

Код должен учитывать, что количество байтов, требуемых в многобайтовой строке символов, может быть больше, чем количество символов в широкой символьной строке. Один широкий символ может приводить к 2 или более байтам в многобайтовой строке символов, в зависимости от используемых кодировок. – 2008-10-19 03:59:15

+0

Можете ли вы привести мне пример? – 2008-10-19 04:04:52

+0

В качестве примера можно привести азиатские символы, но это действительно зависит от кодовой страницы, используемой для преобразования. В вашем примере это, вероятно, не будет проблемой, потому что любой символ, отличный от ANSI, будет заменен вопросительным знаком. – 2008-10-19 06:04:54

32

Затронув answer предоставленной Брайан Р. Бонди: Вот пример, который показывает, почему вы не можете просто размер выходного буфера на количество широких символов в исходной строке:

#include <windows.h> 
#include <stdio.h> 
#include <wchar.h> 
#include <string.h> 

/* string consisting of several Asian characters */ 
wchar_t wcsString[] = L"\u9580\u961c\u9640\u963f\u963b\u9644"; 

int main() 
{ 

    size_t wcsChars = wcslen(wcsString); 

    size_t sizeRequired = WideCharToMultiByte(950, 0, wcsString, -1, 
               NULL, 0, NULL, NULL); 

    printf("Wide chars in wcsString: %u\n", wcsChars); 
    printf("Bytes required for CP950 encoding (excluding NUL terminator): %u\n", 
      sizeRequired-1); 

    sizeRequired = WideCharToMultiByte(CP_UTF8, 0, wcsString, -1, 
             NULL, 0, NULL, NULL); 
    printf("Bytes required for UTF8 encoding (excluding NUL terminator): %u\n", 
      sizeRequired-1); 
} 

И выход:

Wide chars in wcsString: 6 
Bytes required for CP950 encoding (excluding NUL terminator): 12 
Bytes required for UTF8 encoding (excluding NUL terminator): 18 
95

Вот несколько функций (на основе примера Брайана Бонди), которые используют WideCharToMultiByte и MultiByteToWideChar для преобразования между std :: wstring и std :: string, используя utf8, чтобы не потерять никаких данных.

// Convert a wide Unicode string to an UTF8 string 
std::string utf8_encode(const std::wstring &wstr) 
{ 
    if(wstr.empty()) return std::string(); 
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); 
    std::string strTo(size_needed, 0); 
    WideCharToMultiByte     (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); 
    return strTo; 
} 

// Convert an UTF8 string to a wide Unicode String 
std::wstring utf8_decode(const std::string &str) 
{ 
    if(str.empty()) return std::wstring(); 
    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); 
    std::wstring wstrTo(size_needed, 0); 
    MultiByteToWideChar     (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); 
    return wstrTo; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^