2016-08-29 1 views
-5

C++Encoding.Unicode.GetBytes을 구현해야합니다.다른 방법 Encoding.Unicode.GetBytes in native C++

.NET 구현 :

Console.WriteLine("codePage number: " + Encoding.Unicode.CodePage.ToString()); 
Console.Write("string: "); 
foreach (var ch in Encoding.Unicode.GetBytes("string")) 
    Console.Write(ch.ToString("X") + "-"); 
Console.WriteLine(); 
Console.Write("строка: "); 
foreach (var ch in Encoding.Unicode.GetBytes("строка")) 
    Console.Write(ch.ToString("X") + "-"); 
Console.ReadLine(); 

.NET 구현 출력 :

codePage number: 1200 
string: 73-0-74-0-72-0-69-0-6E-0-67-0 
строка: 41-4-42-4-40-4-3E-4-3A-4-30-4 

방법 (.. 등 사용 부스트, QT, 제외)이 메소드를 구현 C++로?


나는 Windows에서이 방법을 발견

#include <exception> 
#include <iostream> 
#include <ostream> 
#include <string> 
#include <Windows.h> 

std::wstring ConvertToUTF16(const std::string & source, const UINT codePage) 
{ 
    // Fail if an invalid input character is encountered 
    static const DWORD conversionFlags = MB_ERR_INVALID_CHARS; 

    // Require size for destination string 
    int utf16Length = ::MultiByteToWideChar(
     codePage,   // code page for the conversion 
     conversionFlags, // flags 
     source.c_str(),  // source string 
     source.length(), // length (in chars) of source string 
     NULL,    // unused - no conversion done in this step 
     0     // request size of destination buffer, in wchar_t's 
    ); 
    if (utf16Length == 0) 
    { 
     const DWORD error = ::GetLastError(); 
     throw std::exception(
      "MultiByteToWideChar() failed: Can't get length of destination UTF-16 string.", 
      error); 
    } 

    // Allocate room for destination string 
    std::wstring utf16Text; 
    utf16Text.resize(utf16Length); 

    // Convert to Unicode 
    if (!::MultiByteToWideChar(
     codePage,   // code page for conversion 
     0,     // validation was done in previous call 
     source.c_str(),  // source string 
     source.length(), // length (in chars) of source string 
     &utf16Text[0],  // destination buffer 
     utf16Text.length() // size of destination buffer, in wchar_t's 
    )) 
    { 
     const DWORD error = ::GetLastError(); 
     throw std::exception(
      "MultiByteToWideChar() failed: Can't convert to UTF-16 string.", 
      error); 
    } 

    return utf16Text; 
} 

void main() 
{ 
    try 
    { 
     // ASCII text 
     std::string inText("string"); 

     // Unicode 
     static const UINT codePage = 1200; 

     // Convert to Unicode 
     const std::wstring utf16Text = ConvertToUTF16(inText, codePage); 

     // Show result 
     for (size_t i = 0; i < utf16Text.size(); i++) 
      printf("%X-", utf16Text[i]); 
    } 
    catch (const std::exception& e) 
    { 
     std::cerr << "*** ERROR:\n"; 
     std::cerr << e.what(); 
     std::cerr << std::endl; 
    } 

    getchar(); 
} 

하지만 MultiByteToWideChar 1200 코드 페이지 (Unicode)에 대한 돌아올 수없는 문자열의 크기를.

+2

스택 오버플로는 코드 변환 서비스가 아닙니다. –

+1

@NicolBolas, 주제, 답변을 읽었습니다. 도움이되지 않습니다. – Align

+0

나는 많은 다른 방법을 시도했다, 나는 필요하다면 나의 발전을 보여 줄 수있다. – Align

답변

1

MultiByteToWideChar()의 코드 페이지 파라미터 UTF-16 인코딩을 FROM 을 변환 할 수 있도록 char 입력 데이터의 인코딩을 지정한다. Win32 프로그래밍에서 코드 페이지 1200을 사용하지 마십시오.

.NET의 문자열은 UTF-16으로 인코딩됩니다. Encoding.Unicode.GetBytes()은 UTF-16LE로 인코딩 된 바이트 배열을 반환합니다. 따라서 문자 데이터는 그대로 바이트로 반환됩니다.

UTF-16 Windows의 경우, wchar_t 또는 char16_t 기반 문자열 (같은 std::wstring 또는 std::u16string)를 사용합니다. 당신이 UTF-16으로 인코딩 된 바이트 배열을해야하는 경우있는 그대로, (예 std::vector와 같은) 2 * length 바이트를 할당하고 원시 문자열의 문자를 복사 또는

std::vector<BYTE> GetUnicodeBytes(const std::wstring &str) 
{ 
    std::vector<BYTE> result; 
    if (!str.empty()) 
    { 
     result.resize(sizeof(wchar_t) * str.length()); 
     CopyMemory(&result[0], str.c_str(), result.size()); 
    } 
    return result; 
} 

std::wcout << L"string: "; 
for (auto ch: GetUnicodeBytes(L"string")) 
    std::wcout << std::hex << (int)ch << L"-"; 
std::wcout << std::endl; 
std::wcout << L"строка: "; 
for (auto ch: GetUnicodeBytes(L"строка")) 
    std::wcout << std::hex << (int)ch << L"-"; 
std::wcout << std::endl; 

:

std::vector<BYTE> GetUnicodeBytes(const std::u16string &str) 
{ 
    std::vector<BYTE> result; 
    if (!str.empty()) 
    { 
     result.resize(sizeof(char16_t) * str.length()); 
     CopyMemory(&result[0], str.c_str(), result.size()); 
    } 
    return result; 
} 

std::wcout << L"string: "; 
for (auto ch: GetUnicodeBytes(u"string")) 
    std::wcout << std::hex << (int)ch << L"-"; 
std::wcout << std::endl; 
std::wcout << L"строка: "; 
for (auto ch: GetUnicodeBytes(u"строка")) 
    std::wcout << std::hex << (int)ch << L"-"; 
std::wcout << std::endl; 
+0

감사합니다. 너는 좋은 인간이야. – Align