2012-12-14 2 views
0

바이트 배열 (워드 문서의 텍스트 포함)에서 LPTSTR (wchar_t *) 객체로 변환하는 데 문제가있는 것처럼 보입니다. 코드가 실행될 때마다 원치 않는 유니 코드 문자가 반환됩니다.바이트 배열의 내용을 wchar_t *

어딘가에서 적절한 호출을하지 않거나 변수를 적절히 사용하지 않기 때문에 그 점을 알 수 있습니다. 그러나이 방법에 접근하는 방법은 확실하지 않습니다. 바라건대 여기 누군가가 올바른 방향으로 나를 안내 할 수 있기를 바랍니다.

먼저 Microsoft Word를 열고 문서의 텍스트를 바이트 배열로 변환하기 위해 C# 코드를 호출합니다. 다음과 같이 문서의

byte document __gc[]; 
document = word->ConvertToArray(filename); 

내용은 다음과 같습니다

다음 문자열 될 수있을 테니까요
{84, 101, 115, 116, 32, 68, 111, 99, 117, 109, 101, 110, 116, 13, 10} 

: "테스트 문서".

우리 다음 단계는 우리가 메모리 할당 시작 라인을 실행하면

byte __pin * value; 

value = &document[0]; 

LPTSTR image; 
image = (LPTSTR)malloc(document->Length + 1); 

을 LPTSTR 변수에의 바이트 배열을 저장하기위한 메모리를 할당하고, 우리의 영상 변수는 무리 가득 도착 원치 않는 유니 코드 문자 :

췍췍췍췍췍췍췍췍﷽﷽����˿於潁 

그리고 우리가 방어 적이기 할 모든 데이터를 통해 전송하는

memcpy(image,value,document->Length); 
단지 더 원하지 않는 유니 코드 문자가 표시됩니다

:

敔瑳䐠捯浵湥൴촊﷽﷽����˿於潁 

나는 우리가 겪고있는 문제를 파악하는 방법 우리가 바이트 배열의 값을 저장하는, 또는 아마도 우리가 데이터를 복사 할 때 관련된 중 하나입니다 바이트 배열에서 LPTSTR 변수로. 내가 잘못하고있는 것을 설명하는 데 도움이되거나, 올바른 방향으로 나를 가리켜 줄 수있는 점에 크게 감사하겠습니다.

+0

"코드가 실행될 때마다 유니 코드 문자가 많이 나옵니다."Windows에서 wchar_t는 유니 코드가 될 수 있다는 것을 알고 있습니까? Windows는 wchar_t 인코딩으로 UTF-16을 사용합니다. – bames53

+0

모든 문자는 유니 코드 문자입니다. – melpomene

+1

'memcpy'는 char와 wchar_t 사이의 변환에 적절한 방법이 아닙니다. 변환을 전혀하지 않습니다. – bames53

답변

5

먼저 텍스트 데이터와 그 텍스트가 어떻게 나타나는지 알아야합니다. 당신을 얻을 것이다 참조는

byteThe Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)char 또는 unsigned char 단지 형식 정의 또는 무언가가 시작했다. 따라서 바이트 배열은 문자열에 대해 char 인코딩을 사용하고 있습니다. 실제로 인코딩을 Windows에서 UTF-16으로 변환해야합니다 (wchar_t). 다음은 Windows에서 이러한 변환을 수행하는 것이 좋습니다 일반적인 방법입니다 :

우리는 두 번 기능 MultiByteToWideChar()를 호출
int output_size = MultiByteToWideChar(CP_ACP,0,value,-1,NULL,0); 
assert(0<output_size); 
wchar_t *converted_buf = new wchar_t[output_size]; 
int size = MultiByteToWideChar(CP_ACP,0,value,-1,converted_buf,output_size); 
assert(output_size==size); 

가 한 번 변환의 결과를 저장하는 데 필요한 방법 버퍼의 큰 파악하고, 두 번째로는, 실제 변환을 수행하기 위해 할당 한 버퍼를 전달합니다.

CP_ACP은 원본 인코딩을 지정하므로 API 설명서를 확인하여 그 값이 무엇인지 확인해야합니다. CP_ACP은 'codepage : Ansi codepage'의 약자로, Microsoft의 '비 유니 코드'프로그램 용 인코딩 설정 '이라고합니다. API는 CP_UTF8 (우리가 희망 할 수 있음) 또는 1252 또는 다른 것과 같은 다른 것을 사용할 수도 있습니다.

다른 인수를 확인하려면 MultiByteToWideChar here에서 나머지 설명서를 참조하십시오.


우리는 우리가 메모리를 할당 시작 줄을 실행하면, 우리의 이미지 변수는 원치 않는 유니 코드 문자의 무리와 함께 채워집니다 : 당신이 malloc()를 호출 할 때

가 제공 한 메모리입니다 초기화되지 않고 그냥 쓰레기가 들어 있습니다. 초기화 전에 확인한 값은 중요하지 않으며 단순히 해당 데이터를 사용하지 않아야합니다. 중요한 데이터는 버퍼로 채우는 데이터뿐입니다. 위의 MultiByteToWideChar() 코드는 문자열을 자동으로 null로 종료하므로 사용하지 않는 버퍼 공간에서 가비지를 볼 수 없으며 버퍼를 할당하는 방법으로 추가 공간이 남지 않습니다.


위 코드는 실제로 C++ 스타일이 아닙니다. Win32에서 제공하는 C 스타일 API의 일반적인 용도 일뿐입니다. 나는 (내가 강제로 해요 경우) 변환을 수행하는 것을 선호하는 방법은 더 같이있다 :. char 인코딩을 가정

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> convert; // converter object saved somewhere 

std::wstring output = convert.from_bytes(value); 

는 (사용

은 UTF-8입니다 당신은 어떤에 대해 다른 codecvt면을 사용해야합니다 다른 인코딩.)

+0

단일 바이트/코드 포인트가 하나 이상의 UTF-16 코드 단위를 요구할 수있는 Windows 코드 페이지가 있습니까? 나는 MBTWC를 두 번 호출하는 것이 옳다는 것에 동의한다. 결과가 예측할 수없는 것인지 궁금하다. : –

+0

@SteveJessop Yes, CP_UTF8. 또 다른 질문은 Windows에서 로캘의 코드 페이지가 대리 코드 포인트가 필요한 문자를 지원하는지 여부입니다. 나는 그것에 대한 답을 알지 못하지만 표준이 위반된다면 (C++ 11 § 3.9.1/5). – bames53

+0

죄송합니다. CP_ACP * 일 수있는 코드 페이지 *를 지정해야합니다. CP_ACP를 전달하면 측정 결과가 문자열의 길이보다 더 많이 반환 될 수 있습니까?이 경우'MultiByteToWideChar'가'strlen (value) + 1'과 동일합니까? MS가 표준을 준수한다고 가정 할 때 대답이 후자 인 것처럼 들립니다. –