2013-04-03 3 views
2

내가 tinyxml2와 함께 사용하기 위해 저장할 수있는 파일 경로 얻기 위해 다음 코드를 사용하고 있습니다 포함이 잘 작동C 반환의 문자가 null 문자

OPENFILENAME ofn; 

char szFileName[MAX_PATH] = ""; 

ZeroMemory(&ofn, sizeof(ofn)); 
ofn.lStructSize = sizeof(ofn); 
ofn.hwndOwner = NULL; 
ofn.lpstrFilter = (LPCWSTR)L"XML Files (*.xml)\0*.xml\0All Files (*.*)\0*.*\0"; 
ofn.lpstrFile = (LPWSTR)szFileName; 
ofn.lpstrFile[0] = '\0'; 
ofn.nMaxFile = MAX_PATH; 
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 
ofn.lpstrDefExt = (LPCWSTR)L"xml"; 
GetSaveFileName(&ofn); 

를하고 있지만 때 대화 상자를 표시합니다 I tinyxml2은 이름이 한 문자 길이있는 파일 및 szFileName의 첫 번째 문자를 저장 끝으로 전달 될 때

szFileName 0x0026f5b0 "C" char[0x00000104] 
[0x00000000] 0x43 'C' char 
[0x00000001] 0x00 '\0' char 
[0x00000002] 0x3a ':' char 
[0x00000003] 0x00 '\0' char 
[0x00000004] 0x5c '\\' char 
[0x00000005] 0x00 '\0' char 
[0x00000006] 0x61 'a' char 
[0x00000007] 0x00 '\0' char 
[0x00000008] 0x73 's' char 
[0x00000009] 0x00 '\0' char 
[0x0000000a] 0x64 'd' char 
[0x0000000b] 0x00 '\0' char 
[0x0000000c] 0x61 'a' char 
[0x0000000d] 0x00 '\0' char 
[0x0000000e] 0x73 's' char 
[0x0000000f] 0x00 '\0' char 
[0x00000010] 0x64 'd' char 
[0x00000011] 0x00 '\0' char 
[0x00000012] 0x61 'a' char 
[0x00000013] 0x00 '\0' char 
[0x00000014] 0x73 's' char 
[0x00000015] 0x00 '\0' char 
[0x00000016] 0x2e '.' char 
[0x00000017] 0x00 '\0' char 
[0x00000018] 0x78 'x' char 
[0x00000019] 0x00 '\0' char 
[0x0000001a] 0x6d 'm' char 
[0x0000001b] 0x00 '\0' char 
[0x0000001c] 0x6c 'l' char 

이 : 많은 널 (null) 문자가 포함 된 것으로 보인다 szFileName에서 반환 된 값을 검색합니다.

각 문자 다음에 이러한 null 문자를 추가하는 이유는 무엇입니까?

+1

'(LPWSTR) szFileName'은 매우 매우 매우 매우 매우 매우 매우 매우 매우 매우 매우 매우 매우 매우 매우 할 아주 나쁜 것. – chris

답변

3

GetSaveFileNameA 대신 GetSaveFileNameW (으)로 전화하고 있습니다. szFileNameTCHAR (또는 WCHAR)의 배열로 선언하십시오.

GetSaveFileName은 코드 (또는 프로젝트 설정)의 #define에 따라 GetSaveFileNameW 또는 GetSaveFileNameA이라는 이름으로 해석됩니다. 기본적으로 현대 Visual Studio 버전에서는 _UNICODE ("와이드 charater")을 정의합니다.

특정 문자 집합이 필요한 다른 라이브러리로 전달하면 WideCharToMultiByte 또는 관련 함수를 사용하여 변환해야 할 수 있습니다.

또한 szFileName (char[MAX_PATH]) 및 (LPWSTR)과 같이 한 유형을 호환되지 않는 다른 유형으로 강제 변경하지 마십시오.

+1

이것을 확장하기 위해'GetSaveFileName'은 빌드 설정에 따라'GetSaveFileNameA' 또는'GetSaveFileNameW'로 해석 할 매크로입니다. 이것이'TCHAR'을 사용해야하는 이유입니다. 왜냐하면 그것도 빌드 설정으로 바뀔 것이기 때문입니다. – IronMensan

+0

"댓글 추가"버튼 위에 마우스를 올려 놓았을 때 "이 게시물이 수정되었습니다"팝업이 보입니다. – IronMensan

+0

고마워, 나는 내가 주위에 놀고있는 게시 한 예제를 준 다른 사이트에 포럼 스레드를 따라 갔다 - 분명히 여기에 의견으로 판단하는 좋은 시작되지 않았습니다! 문자 집합에 대한 통찰력을 가져 주셔서 감사합니다 - 이제는 의도 한대로 작동하도록했습니다! –

0

내가는 Win32 API의 어떤 전문가는 아니지만, : 당신은 "16 비트 유니 코드 문자의 문자열을 32 비트 포인터"인 LPWSTR를 사용하는

ofn.lpstrFile = (LPWSTR)szFileName; 

. 즉, 각 문자는 2 바이트 이상으로 인코딩됩니다. ASCII 문자 값이 단일 바이트에 맞기 때문에 두 번째 문자는 항상 0으로 설정됩니다.