천객만래 [千客萬來] (It has an interminable succession of visitors)

[개발/VC++] API를 이용한 ASCII와 UNICODE변환및 코드페이지를 이용한 변환방법



출처 : 인터넷


API를 이용한 ASCII와 UNICODE변환및 코드페이지를 이용한 변환방법 
 


[사용예제]

// 멀티바이트문자열 --> 와이드문자열
 char chText[100] = "abcdefg";  // 멀티바이트 문자열
 wchar_t* pszTmp = NULL; // 와이드만자열로 변경해서 저장될 주소
 int iLen = ::MultiByteToWideChar(CP_ACP, 0, pszText, -1, pszTmp, 0);
 pszTmp = new wchar_t[iLen+1];
 ::MultiByteToWideChar(CP_ACP, 0, pszText, -1, pszTmp, iLen);

 wchar_t tcResult[MAX_PATH] = _T("");
 wcscpy( tcResult, pszTmp ); 
 delete [] pszTmp;


// 와이드문자열 --> 멀티바이트문자열
wchar_t wcText[100] = _T("abcdefg");
char* pTemp = NULL;
int iLen = ::WideCharToMultiByte(CP_ACP, 0, wcText, -1, pTemp, 0, NULL, NULL);
pTemp = new char[iLen+1];
::WideCharToMultiByte(CP_ACP, 0, wcText, -1, pTemp, iLen, NULL, NULL);

char chResult[MAX_PAHT] = "";
strcpy( chResult, pszTemp );
delete [] pTemp;

 

 


 

 

 
Counter. 215

 

 
=========================================================
● API를 이용한 ASCII와 UNICODE의 변환방법
=========================================================
//////////////////////////////////////////////////
// 문자열을 유니코드 문자열(wide-character)로 매핑한다.
//
// 이 함수에 의해 매핑되는 문자열은 multibyte character set으로 부터 반드시 유래하는 건 아니다.
//////////////////////////////////////////////////
int MultiByteToWideChar (
UINT CodePage, // code page
DWORD dwFlags, // character-type options
LPCSTR lpMultiByteStr, // string to map
int cbMultiByte, // number of bytes in string
LPWSTR lpWideCharStr, // wide-character buffer
int cchWideChar // size of buffer
);
CodePage :
[in] 변환 수행에 사용될 code page를 기술한다.
이 파라메타는 설치되거나 또는 시스템에 유효한 어떤한 코드페이지가 될수 있다.
또는 아래에 기술된 값중 하나를 기술할 수 있다.

CP_ACP : ANSI 코드 페이지
CP_MACCP : Macintosh 코드 페이지
CP_OEMCP : OEB 코드 페이지

lpMultiByteStr :
[in] 변환 되어질 문자열 스트링 포인터

cbMultiByte
[in] lpMultiByteStr 파라메타에 의해 포인트된 문자열의 바이트 사이즈
lpWideCharStr
[out] 변환된 문자열을 수신할 버퍼 포인터
cchWideChar
[in] wide character로, lpWideCharStr파라메타에 의해 포인트된 버퍼의 크기
만약 이값이 0이면, 이함수는 wide character로 요구되어진 buffer size를 반환한다,
그리고 lpWideCharStr 버퍼의 사용을 하지 않는다.
Return Values

If the function succeeds, and cchWideChar is nonzero, the return value is the number of wide characters written to the buffer pointed to by lpWideCharStr.
If the function succeeds, and cchWideChar is zero, the return value is the required size, in wide characters, for a buffer that can receive the translated string.
If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:
ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER
ERROR_NO_UNICODE_TRANSLATION
▷ASCII ==> UNICODE 변환방법
// sTime이란 ANSI 무낮열을 bstr이란 이름의 유니코드(BSTR타입) 변수로 변환
char sTime[] = '유니코드 변환 예제';
BSTR bstr;
// sTime을 유니코드로 변환하기에 앞서 먼저 그것의 유니코드에서의 길이를 알아야 한다.
int nLen = MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), NULL, NULL)
// 얻어낸 길이만큼 메모리를 할당한다.
bstr = SysAllocStringLen(NULL, nLen);
// 이제 변환을 수행한다.
MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), bstr, nLen);
▷UNICODE ==> ASCII 변환방법
// newVal이란 BSTR 타입에 있는 유니코드 문자열을 sTime이라는 ANSI 문자열로 변환
char sTime[128];
WideCharToMultiByte(CP_ACP, 0, newVal, -1, sTime, 127/*원래크기보다 1작게*/, NULL, NULL);

===================================================
● 코드 페이지를 이용하여 조합/완성/유니코드를 주무르자.
====================================================
윈도우즈 API에서 MultiByteToWideChar와 WideCharToMultiByte를 이용하면 완성,
조합에서 유니코드로 혹은 그 반대로 변환을 할 수 있습니다.
한글 95나 NT의 경우 기본적으로 조합형과 완성형의 코드페이지가 설치 되어있으므로 문제가 없으나
영문의 경우는 IE에서 한글 package를 설치하면 완성형은 설치가 되나 조합형은 없습니다.
코드페이지 설치.
'CP_XXX.nls'(WIN95) or 'C_XXX.nls'(WINNT)를 구하십시요. XXX 는 1361(조합) or 949(완성)입니다.
레지스트리에 다음의 값을 입력하십시요.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\XXX=CP_XXX.nls (WIN95)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\XXX=C_XXX.nls (WINNT)
조합형 코드를 보고자 할때는 cp_1361.nls(95용), c_1361.nls(nt용)을 구하셔서 시스템에 설치를 합니다.
95의 경우 system 디렉토리에, NT의 경우 system32 디렉토리에 설치하십시요.
=====================================================================
/*
* MultiByteToWideChar와 WideCharToMultiByte를 이용한 완성형, 조합형, 유니코드 변환.
*/
#include
#define CP_WANSUNG 949
#define CP_JOHAB 1361

void ConvertWansungToUnicode (LPCSTR szInput, int nInputSize, LPWSTR* szUnicode, int* nUnicodeSize)
{
// 유니코드의 크기를 구한다.
*nUnicodeSize = MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
NULL, 0);
*szUnicode = (LPWSTR)malloc(nUnicodeSize*sizeof(WCHAR));
// 실제 유니코드로 변환.
MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
*szUnicode, *nUnicodeSize);
}
void ConvertJohabToUnicode (LPCSTR szInput, int nInputSize, LPWSTR* szUnicode, int* nUnicodeSize)
{
// 유니코드의 크기를 구한다.
*nUnicodeSize = MultiByteToWideChar(CP_JOHAB, 0,
szInput, nInputSize,
NULL, 0);
*szUnicode = (LPWSTR)malloc(nUnicodeSize*sizeof(WCHAR));
// 실제 유니코드로 변환.
MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
*szUnicode, *nUnicodeSize);
}
void ConvertWansungToJohab (LPCSTR szInput, int nInputSize, LPSTR* szOutput, int* nOutputSize)
{
int nUnicodeSize;
LPWSTR szUnicode;
// 1. 완성형을 유니코드로 변환
// 유니코드의 크기를 구한다.
nUnicodeSize = MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
NULL, 0);
szUnicode = (LPWSTR)malloc(nUnicodeSize*sizeof(WCHAR));
// 실제 유니코드로 변환.
MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
szUnicode, nUnicodeSize);
// 2. 유니코드를 조합형으로 변환.
// 조합형의 크기를 구한다.
*nOutputSize = WideCharToMultiByte(CP_JOHAB, 0,
szUnicode, nUnicodeSize,
NULL, 0, NULL,NULL);
*szOutput = (LPSTR)malloc(*nOutputSize);
// 실제 조합형으로 변환.
WideCharToMultiByte(CP_JOHAB, 0,
szUnicode, nUnicodeSize,
*szOutput, *nOutputSize, NULL,NULL);
free(szUnicode);
}
유니코드 문자열을 UTF8 문자열로 변환하는 방법

KB Article ID: K001368

--------------------------------------------------------------------------------

이 내용이 적용되는 제품:
- Platform SDK

[요 약]

한글 윈도우 95에서 유니코드 문자열을 UTF8 문자열로 변환해 주는 다음 함수를 실행하면, 리턴되는 UTF8 버퍼에 아무런 값도 리턴 되지 않습니다. RFC2044에 명시된 스펙에 의거하여 문자열 변환하는 방법을 소개합니다.

#include “winnls.h”
WideCharToMultiByte(CP_UTF8, 0, szUniBuf, nUniLen, szUTFBuf, sizeof(szUTFBuf), NULL, NULL);

[추가 정보]

한글 윈도우 95에서 WIN32 API인 WideCharToMultiByte(CP_UTF8, xxx) 함수에서 UTF8 버퍼에 아무런 값도 리턴하지 않으므로 다음과 같이 스펙에 의거한 변환 루틴을 이용하여 UTF8 문자열 값을 얻습니다.

char* UnicodeToUTF8(wchar_t uc, char* UTF8)
{
if (uc <= 0x7f)
{
UTF8[0] = (char) uc;
UTF8[1] = (char) '\0';
}
else if (uc <= 0x7ff)
{
UTF8[0] = (char) 0xc0 + uc / (wchar_t) pow(2, 6);
UTF8[1] = (char) 0x80 + uc % (wchar_t) pow(2, 6);
UTF8[2] = (char) '\0';
}
else if (uc <= 0xffff)
{
UTF8[0] = (char) 0xe0 + uc / (wchar_t) pow(2, 12);
UTF8[1] = (char) 0x80 + uc / (wchar_t) pow(2, 6) % (wchar_t) pow(2, 6);
UTF8[2] = (char) 0x80 + uc % (wchar_t) pow(2, 6);
UTF8[3] = (char) '\0';
}

return UTF8;
}

int WideStrToUTF8Str(wchar_t *szUni,char *szUTF8)
{
int i=0;
char TempUTF8[10];
for(i=0;szUni[i];i++) {
UnicodeToUTF8(szUni[i], TempUTF8);
strcat(szUTF8, TempUTF8);
}
return strlen(szUTF8);
}

실제 위 두 함수를 사용하는 예제

{
wchar_t szUniBuf[MAXBUF];
int nUniLen, nUTFLen;
char szUTFBuf[MAXBUF];

nUniLen = MultiByteToWideChar(CP_ACP, 0, szHello, strlen(szHello), szUniBuf, MAXBUF);
szUniBuf[nUniLen] = 0;
memset(szUTFBuf, 0, MAXBUF);
nUTFLen = WideStrToUTF8Str(szUniBuf, szUTFBuf);
//nUTFLen = WideCharToMultiByte(CP_UTF8, 0, szUniBuf, nUniLen, szUTFBuf, MAXBUF, NULL, NULL);
szUTFBuf[nUTFLen]=0x00;

}


한글 EBCIDIC 코드를 한글 ASCII 코드로 변환하는 방법

KB Article ID: K001143

--------------------------------------------------------------------------------

[요 약]

프로그래밍적으로, 한글 EBCIDIC 코드를 한글 ASCII 코드로 변환하는 방법을
여기에서 소개한다.

[추가 정보]

#include 'snanls.h'
function()
{
int ret;
LPCTSTR lpSrcStr, lpDestStr;
ret =SnaInit(CP_949);
printf('ret = %d', ret);
ret = SnaNlsMapString (lpSrcStr, lpDestStr, CP_933, CP_949, 2, 2,
SNA_MULTIBYTE, SNA_MULTIBYTE, 0x0);
printf('ret = %d', ret);
}


1. SnaInit(CP_949)는 현재 이 프로그램이 실행되는 환경의 코드 페이지를
지정한다.
2. lpSrcStr은 IBM 메인 프레임 컴퓨터 등으로부터 받은 한글 EBCIDIC 코드이며,
lpDestStr은 리턴되는 ASCII 코드값이다.
3. #define CP_933 933 /* EBCDIC Korean */
#define CP_949 949 /* Korean */
UTF-8 to Unicode / Unicode to UTF-8 transformation 


Posted by SB패밀리

[개발/VC++] 유니코드 버전으로 된 프로젝트에서 CString 를 char* 로 바꾸는 방법





MFC에서 유니코드 버전으로 된 프로젝트에서 CString 를 char* 로 바꾸는 방법은
유니코드 상태에서 CString 을 바로 CHAR* 로 바꾸는 것이 안됩니다.

W2A 나 A2W 로 코드 변환을 하거나 wsprintf(); 함수를 이용 하면 됩니다.

유니코드는 사용 되는 바이트 수가 2바이트이고 1바이트 문자열로 변환하면 깨져 버리는 문자열 들이 있는데  처리를 해야 합니다. 

유니코드를 멀티바이트 코드로 변환 하려면 

char Text[80];
wsprintfA(Text, "%S", L"문자열" );

멀티바이트 코드를 유니코드로 변환 하려면 

WCHAR Text[80];
wsprintfW(Text, L"%S", "문자열" );


변환될 문자열을 %S(대문자)로 wsprintf()함수를 사용합니다.

※ 현재로써는 바로 CString 에서 char*(LPSTR , LPCSTR) 로 변환 할수 없습니다. 

참고로 더 설명을 하면 CString 기본 요소는 CStringBase<WCHAR>  , CStringBase<CHAR> 둘로 나누어집니다.
이 두 클래스 사이에서 바로 입력 변환이 불가능 합니다. 

변환시에는 API 함수로 코드 변환 후에 사용 해야 하며 
CStringBase<CHAR> 로 사용 한다면 유니코드 내에서 ANSI 코드를 사용 할 수 있습니다. 

또 다른 방법의 함수
-----------------------------
CString을 유니코드로

CString tmp("test");
WCHAR m_wPath[MAX_PATH];

wcscpy(wPath,tmp.GetBuffer(0));



Posted by SB패밀리

[개발/MFC] VC++/MFC API 팁



1. 특정 디렉토리 뒤지기
2. API를 이용하는 유니코드와 ANSI 문자열간의 변환 방법 
3. 윈도우 탐색기로부터의 Drag&Drop을 받으려면
4. 시스템의 모든 드라이브 알아내기
5. 레지스트리 읽기/쓰기



1. 특정 디렉토리 뒤지기 

지정한 디렉토리에 있는 모든 파일을 찾아내는 코드를 만들려면 어떻게 해야 합니까 ?

이 때 사용할 수 있는 API가 바로 FindFirstFile과 FindNextFile, FindClose라는 API들입니다. 사용 예제는 다음과 같습니다.

WIN32_FIND_DATA  findFileData; 
HANDLE hFileHandle;

// szDir에 뒤지고자 하는 디렉토리의 경로명을 준다. 예를 들면 "C:\\TEMP\\*.*" 
// 찾아진 파일의 속성은 findFileData의 dwFileAttributes를 살펴본다. 
hFileHandle = FindFirstFile(m_szDir, &findFileData);  
if (hFileHandle != INVALID_HANDLE_VALUE)  // 파일을 찾은 경우 

 // 찾은 파일의 이름은 cFileName 필드로 들어온다. 
 ... 
 // 다음 파일을 찾는다. 
 while(FindNextFile(hFileHandle, &findFileData)) { 
  ... 
 } 
 FindClose(hFileHandle); 
}


2. API를 이용하는 유니코드와 ANSI 문자열간의 변환 방법
 
API를 이용해서 유니코드와 ANSI 문자열간의 변환은 어떻게 수행합니까 ?

Visual C++에서 유니코드 문자열은 BSTR이란 타입으로 표시됩니다. 또 유니코드와 ANSI 문자열간의 변환을 위해서 윈도우 시스템에는 MultiByteToWideChar와 WideCharToMultiByte라는 API가 존재합니다. MFC에서의 BSTR 타입 변환방법이나 ATL로 하는 BSTR 타입 변환도 참고하시기 바랍니다.


ANSI 문자열에서 유니코드로의 변환 방법

// sTime이란 ANSI 문자열을 bstr이란 이름의 유니코드(BSTR 타입) 변수로 변환 
char sTime[] = "유니코드 변환 예제"; 
BSTR bstr;

// sTime을 유니코드로 변환하기에 앞서 먼저 그 길이를 알아야 한다. 
int nLen = MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), NULL, NULL); 
// 얻어낸 길이만큼 메모리를 할당한다. 
bstr = SysAllocStringLen(NULL, nLen); 
// 이제 변환을 수행한다. 
MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), bstr, nLen); 
// 필요없어지면 제거한다. 
SysFreeString(bstr);


유니코드에서 ANSI 문자열로의 변환 방법

// newVal이란 BSTR 타입에 있는 유니코드 문자열을 sTime이라는 ANSI 문자열로 변환 
char *sTime; 
int nLen = WideCharToMultiByte(CP_ACP, 0, newVal, -1, sTime, 0, NULL, NULL); 
sTime = malloc(nLen+1); 
WideCharToMultiByte(CP_ACP, 0, newVal, -1, sTime, 128, NULL, NULL); 
// 필요없으면 메모리를 제거한다. 
free(sTime);

유니코드 문자열을 UTF-8으로 변환하기

WideCharToMultiByte 함수를 호출할 때 첫 번째 인자로 CP_UTF8을 지정하면 된다.UTF-8은 유니코드의 인코딩 스킴 중의 하나로 쉽게 말하자면 문자열 스트림에서 0을 빼고 표현하는 방법이라고 볼 수 있다 


3. 윈도우 탐색기로부터의 Drag&Drop을 받으려면

윈도우 탐색기로부터 제가 만든 윈도우로의 drag&drop이 가능하게 하려면 어떻게 해야 합니까 ?

다음 순서를 따라서 프로그래밍하시면 됩니다.

프로그램의 초기화시에 DragAcceptFiles(hWnd, TRUE) 함수를 호출한다. 첫 번째 인자인 hWnd는 드롭의 타겟이 되는 윈도우의 핸들이다. 
탐색기로부터 파일이 드롭되는 순간에 WM_DROPFILES 메시지가 날라온다. 이를 처리한다.

case WM_DROPFILES : 

 POINT pt; 
 // 어느 위치에 드롭되었는지 그 항목을 알아낸다. 
 if (DragQueryPoint((HDROP)wParam, &pt)) 
 { 
  UINT i = 0; 
  // 모두 몇 개의 파일이 드롭되었는지 알아낸다. 
  // 만일 폴더가 드롭되었다면 폴더의 이름만 넘어온다. 
  UINT uCount = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL ,0);

  for(i = 0;i < uCount;i++) 
  { 
  // 드롭된 파일의 이름을 알아온다. 
  DragQueryFile((HDROP)wParam, i, buffer ,255); 
  // 드롭된 파일 이름을 출력해본다. 
  MessageBox(hWnd, buffer, "File Name", MB_OK); 
  } 
 } 
 // drag and drop 작업을 끝낸다. 
 DragFinish((HDROP)wParam); 
 break; 

Drag&drop을 더 사용할 필요가 없어지면 DragAcceptFiles를 호출한다. 
DragAcceptFiles(hWnd, FALSE); 


4. 시스템의 모든 드라이브 알아내기

현재 시스템에 붙어있는 모든 드라이브(네트웍 드라이브 포함)에 대한 정보를 알아내고 싶습니다.

GetLogicalDriveStrings로 시스템에 마운트되어있는 모든 드라이브 정보를 알아낸다. 두 번째 인자인 buffer로 드라이브 정보가 들어오는데 그 구조는 c:\,d:\과 같은 형식이며 리턴값으로 그 버퍼의 크기가 들어온다.

char buffer[256]; 
DWORD dwRet; 
LPSTR token;

dwRet = GetLogicalDriveStrings(256, buffer);

// 루프를 돌면서 드라이브별 정보를 알아낸다. 이 때는 GetVolumeInformation 함수를 이용한다.

token = buffer; // token이 지금 처리해야할 드라이브를 가리킨다. 
while (dwRet > 0) 

 DWORD FileSystemFlag; 
 char FileSystemName[64];

 strcpy(DriveString, token); 
 // VolumeName으로 드라이브에 대한 설명 문자열이 넘어온다. 
 if (GetVolumeInformation(token, VolumeName, 255, NULL, NULL, 
      &FileSystemFlag, FileSystemName, 63)) 
 { 
  // 원하는 작업을 수행한다. 
 } 
 dwRet -= (strlen(token)+1); 
 token = token + strlen(token)+1; // 다음 드라이브로 진행한다. 
}
 

5. 레지스트리 읽기/쓰기

API를 이용해서 레지스트리에 한 항목을 생성하거나 기존 항목의 값을 읽어들이려면 어떻게 해야합니까 ?

레지스트리 관련 API를 사용하려면 winreg.h라는 헤더 파일을 소스에 포함해야 합니다. 레지스트리에 키를 생성하는 방법과 레지스트리에 존재하는 키의 값을 읽는 방법을 차례로 살펴보겠습니다.


레지스트리 키 생성 예제

// 예를 들어 HKEY_LOCAL_MACHINE밑의 System\CurrentControlSet\Services\GenPort라는 키를 
// 생성하고 거기에 DWORD 타입의 값으로 Type을 만들고 문자열 타입의 값으로 Group 
// 을 만들어 본다. 
#include "winreg.h" 
LONG error = 0; 
HKEY hKey; 
DWORD dwDisp, dwData; 
char lpData[] = "Write this down";

// 먼저 만들려는 키가 이미 존재하는 것인지 살혀본다. 
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\GenPort", 
                        0, KEY_ALL_ACCESS, &hKey);

if (error != ERROR_SUCCESS) // 없다면 새로 생성한다. 

 // 키를 생성한다. 
 error = RegCreateKeyEx(HKEY_LOCAL_MACHINE, 
  "System\\CurrentControlSet\\Services\\GenPort", 0, "REG_BINARY", 
         REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &dwDisp); 
        // 위의 키 밑에 Type이란 DWORD 타입의 값을 만들고 1로 초기화 
 dwData = 0x1; 
 error = RegSetValueEx( hKey, "Type", 0, REG_DWORD,&dwData,4); 
        // 위의 키 밑에 Group이란 문자열 타입의 값을 만들고 lpData의 값으로 초기화 
 error = RegSetValueEx( hKey, "Group", 0, REG_SZ, lpData, strlen(lpData));

        // 키를 닫는다. 
 RegCloseKey(hKey); 
}

기존의 레지스트리 키에서 값 읽기

// HKEY_CURRENT_USER\Software\Netscape\Netscape Navigator\Main 밑의 Install Directory 
// 값의 문자열 값을 읽어들인다. 
DWORD dwType, cbData; 
HKEY hSubKey; 
long lRet; 
char pszString[255];

// 키를 오픈한다. 
if ((lRet = RegOpenKeyEx(HKEY_CURRENT_USER, 
                "Software\\Netscape\\Netscape Navigator\\Main", 
  0, KEY_READ | KEY_QUERY_VALUE , &hSubKey)) == ERROR_SUCCESS) 

 cbData = 255; // 문자열 값을 읽어올 데이터의 크기를 준다. 
 if ((lRet = RegQueryValueEx(hSubKey, "Install Directory", 
  NULL, &dwType, pszString, &cbData)) == ERROR_SUCCESS) 
 { 
  // 제대로 읽힌 경우 
 } 
 else 
 { 
  // 에러가 발생한 경우 
 } 
 RegCloseKey(hSubKey); 
}

레지스트리 키 삭제하기 
- RegDeleteKey 함수를 사용한다.

Posted by SB패밀리


1. 특정 디렉토리 뒤지기
2. API를 이용하는 유니코드와 ANSI 문자열간의 변환 방법
3. 윈도우 탐색기로부터의 Drag&Drop을 받으려면
4. 시스템의 모든 드라이브 알아내기
5. 레지스트리 읽기/쓰기

1. 특정 디렉토리 뒤지기

지정한 디렉토리에 있는 모든 파일을 찾아내는 코드를 만들려면 어떻게 해야 합니까 ?

이 때 사용할 수 있는 API가 바로 FindFirstFile과 FindNextFile, FindClose라는 API들입니다. 사용 예제는 다음과 같습니다.

WIN32_FIND_DATA  findFileData;
HANDLE hFileHandle;

// szDir에 뒤지고자 하는 디렉토리의 경로명을 준다. 예를 들면 "C:\\TEMP\\*.*"
// 찾아진 파일의 속성은 findFileData의 dwFileAttributes를 살펴본다.
hFileHandle = FindFirstFile(m_szDir, &findFileData); 
if (hFileHandle != INVALID_HANDLE_VALUE)  // 파일을 찾은 경우
{
 // 찾은 파일의 이름은 cFileName 필드로 들어온다.
 ...
 // 다음 파일을 찾는다.
 while(FindNextFile(hFileHandle, &findFileData)) {
  ...
 }
 FindClose(hFileHandle);
}


2. API를 이용하는 유니코드와 ANSI 문자열간의 변환 방법
 
API를 이용해서 유니코드와 ANSI 문자열간의 변환은 어떻게 수행합니까 ?

Visual C++에서 유니코드 문자열은 BSTR이란 타입으로 표시됩니다. 또 유니코드와 ANSI 문자열간의 변환을 위해서 윈도우 시스템에는 MultiByteToWideChar와 WideCharToMultiByte라는 API가 존재합니다. MFC에서의 BSTR 타입 변환방법이나 ATL로 하는 BSTR 타입 변환도 참고하시기 바랍니다.


ANSI 문자열에서 유니코드로의 변환 방법

// sTime이란 ANSI 문자열을 bstr이란 이름의 유니코드(BSTR 타입) 변수로 변환
char sTime[] = "유니코드 변환 예제";
BSTR bstr;

// sTime을 유니코드로 변환하기에 앞서 먼저 그 길이를 알아야 한다.
int nLen = MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), NULL, NULL);
// 얻어낸 길이만큼 메모리를 할당한다.
bstr = SysAllocStringLen(NULL, nLen);
// 이제 변환을 수행한다.
MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), bstr, nLen);
// 필요없어지면 제거한다.
SysFreeString(bstr);


유니코드에서 ANSI 문자열로의 변환 방법

// newVal이란 BSTR 타입에 있는 유니코드 문자열을 sTime이라는 ANSI 문자열로 변환
char *sTime;
int nLen = WideCharToMultiByte(CP_ACP, 0, newVal, -1, sTime, 0, NULL, NULL);
sTime = malloc(nLen+1);
WideCharToMultiByte(CP_ACP, 0, newVal, -1, sTime, 128, NULL, NULL);
// 필요없으면 메모리를 제거한다.
free(sTime);

유니코드 문자열을 UTF-8으로 변환하기

WideCharToMultiByte 함수를 호출할 때 첫 번째 인자로 CP_UTF8을 지정하면 된다.UTF-8은 유니코드의 인코딩 스킴 중의 하나로 쉽게 말하자면 문자열 스트림에서 0을 빼고 표현하는 방법이라고 볼 수 있다


3. 윈도우 탐색기로부터의 Drag&Drop을 받으려면

윈도우 탐색기로부터 제가 만든 윈도우로의 drag&drop이 가능하게 하려면 어떻게 해야 합니까 ?

다음 순서를 따라서 프로그래밍하시면 됩니다.

프로그램의 초기화시에 DragAcceptFiles(hWnd, TRUE) 함수를 호출한다. 첫 번째 인자인 hWnd는 드롭의 타겟이 되는 윈도우의 핸들이다.
탐색기로부터 파일이 드롭되는 순간에 WM_DROPFILES 메시지가 날라온다. 이를 처리한다.

case WM_DROPFILES :
{
 POINT pt;
 // 어느 위치에 드롭되었는지 그 항목을 알아낸다.
 if (DragQueryPoint((HDROP)wParam, &pt))
 {
  UINT i = 0;
  // 모두 몇 개의 파일이 드롭되었는지 알아낸다.
  // 만일 폴더가 드롭되었다면 폴더의 이름만 넘어온다.
  UINT uCount = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL ,0);

  for(i = 0;i < uCount;i++)
  {
  // 드롭된 파일의 이름을 알아온다.
  DragQueryFile((HDROP)wParam, i, buffer ,255);
  // 드롭된 파일 이름을 출력해본다.
  MessageBox(hWnd, buffer, "File Name", MB_OK);
  }
 }
 // drag and drop 작업을 끝낸다.
 DragFinish((HDROP)wParam);
 break;
}
Drag&drop을 더 사용할 필요가 없어지면 DragAcceptFiles를 호출한다.
DragAcceptFiles(hWnd, FALSE);


4. 시스템의 모든 드라이브 알아내기

현재 시스템에 붙어있는 모든 드라이브(네트웍 드라이브 포함)에 대한 정보를 알아내고 싶습니다.

GetLogicalDriveStrings로 시스템에 마운트되어있는 모든 드라이브 정보를 알아낸다. 두 번째 인자인 buffer로 드라이브 정보가 들어오는데 그 구조는 c:\,d:\과 같은 형식이며 리턴값으로 그 버퍼의 크기가 들어온다.

char buffer[256];
DWORD dwRet;
LPSTR token;

dwRet = GetLogicalDriveStrings(256, buffer);

// 루프를 돌면서 드라이브별 정보를 알아낸다. 이 때는 GetVolumeInformation 함수를 이용한다.

token = buffer; // token이 지금 처리해야할 드라이브를 가리킨다.
while (dwRet > 0)
{
 DWORD FileSystemFlag;
 char FileSystemName[64];

 strcpy(DriveString, token);
 // VolumeName으로 드라이브에 대한 설명 문자열이 넘어온다.
 if (GetVolumeInformation(token, VolumeName, 255, NULL, NULL,
      &FileSystemFlag, FileSystemName, 63))
 {
  // 원하는 작업을 수행한다.
 }
 dwRet -= (strlen(token)+1);
 token = token + strlen(token)+1; // 다음 드라이브로 진행한다.
}


5. 레지스트리 읽기/쓰기

API를 이용해서 레지스트리에 한 항목을 생성하거나 기존 항목의 값을 읽어들이려면 어떻게 해야합니까 ?

레지스트리 관련 API를 사용하려면 winreg.h라는 헤더 파일을 소스에 포함해야 합니다. 레지스트리에 키를 생성하는 방법과 레지스트리에 존재하는 키의 값을 읽는 방법을 차례로 살펴보겠습니다.


레지스트리 키 생성 예제

// 예를 들어 HKEY_LOCAL_MACHINE밑의 System\CurrentControlSet\Services\GenPort라는 키를
// 생성하고 거기에 DWORD 타입의 값으로 Type을 만들고 문자열 타입의 값으로 Group
// 을 만들어 본다.
#include "winreg.h"
LONG error = 0;
HKEY hKey;
DWORD dwDisp, dwData;
char lpData[] = "Write this down";

// 먼저 만들려는 키가 이미 존재하는 것인지 살혀본다.
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\GenPort",
                        0, KEY_ALL_ACCESS, &hKey);

if (error != ERROR_SUCCESS) // 없다면 새로 생성한다.
{
 // 키를 생성한다.
 error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  "System\\CurrentControlSet\\Services\\GenPort", 0, "REG_BINARY",
         REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &dwDisp);
        // 위의 키 밑에 Type이란 DWORD 타입의 값을 만들고 1로 초기화
 dwData = 0x1;
 error = RegSetValueEx( hKey, "Type", 0, REG_DWORD,&dwData,4);
        // 위의 키 밑에 Group이란 문자열 타입의 값을 만들고 lpData의 값으로 초기화
 error = RegSetValueEx( hKey, "Group", 0, REG_SZ, lpData, strlen(lpData));

        // 키를 닫는다.
 RegCloseKey(hKey);
}

기존의 레지스트리 키에서 값 읽기

// HKEY_CURRENT_USER\Software\Netscape\Netscape Navigator\Main 밑의 Install Directory
// 값의 문자열 값을 읽어들인다.
DWORD dwType, cbData;
HKEY hSubKey;
long lRet;
char pszString[255];

// 키를 오픈한다.
if ((lRet = RegOpenKeyEx(HKEY_CURRENT_USER,
                "Software\\Netscape\\Netscape Navigator\\Main",
  0, KEY_READ | KEY_QUERY_VALUE , &hSubKey)) == ERROR_SUCCESS)
{
 cbData = 255; // 문자열 값을 읽어올 데이터의 크기를 준다.
 if ((lRet = RegQueryValueEx(hSubKey, "Install Directory",
  NULL, &dwType, pszString, &cbData)) == ERROR_SUCCESS)
 {
  // 제대로 읽힌 경우
 }
 else
 {
  // 에러가 발생한 경우
 }
 RegCloseKey(hSubKey);
}

레지스트리 키 삭제하기
- RegDeleteKey 함수를 사용한다.

Posted by SB패밀리

[MFC] UTF8로 파일저장하기

CString strFilePath = dlg.GetPathName();

// UTF8로 컨버팅
int nAllocLen = WideCharToMultiByte (CP_UTF8, 0, strSaveData, -1, NULL, 0, NULL, NULL);
CHAR * pBuffer = new CHAR [nAllocLen + 1];
memset (pBuffer, 0, nAllocLen);
WideCharToMultiByte (CP_UTF8, 0, strSaveData, -1, pBuffer, nAllocLen + 1, NULL, NULL);

// 파일로 저장
CFile file;
file.Open (strFilePath, CFile::modeCreate | CFile::modeWrite);
file.Write (pBuffer, nAllocLen);

// 메모리 해제
delete [] pBuffer;

 

Posted by SB패밀리

출처 : 인터넷


API를 이용한 ASCII와 UNICODE변환및 코드페이지를 이용한 변환방법
 


[사용예제]

// 멀티바이트문자열 --> 와이드문자열
 char chText[100] = "abcdefg";  // 멀티바이트 문자열
 wchar_t* pszTmp = NULL; // 와이드만자열로 변경해서 저장될 주소
 int iLen = ::MultiByteToWideChar(CP_ACP, 0, pszText, -1, pszTmp, 0);
 pszTmp = new wchar_t[iLen+1];
 ::MultiByteToWideChar(CP_ACP, 0, pszText, -1, pszTmp, iLen);

 wchar_t tcResult[MAX_PATH] = _T("");
 wcscpy( tcResult, pszTmp );
 delete [] pszTmp;


// 와이드문자열 --> 멀티바이트문자열
wchar_t wcText[100] = _T("abcdefg");
char* pTemp = NULL;
int iLen = ::WideCharToMultiByte(CP_ACP, 0, wcText, -1, pTemp, 0, NULL, NULL);
pTemp = new char[iLen+1];
::WideCharToMultiByte(CP_ACP, 0, wcText, -1, pTemp, iLen, NULL, NULL);

char chResult[MAX_PAHT] = "";
strcpy( chResult, pszTemp );
delete [] pTemp;

 

 


 

 

 
Counter. 215

 

 
=========================================================
● API를 이용한 ASCII와 UNICODE의 변환방법
=========================================================
//////////////////////////////////////////////////
// 문자열을 유니코드 문자열(wide-character)로 매핑한다.
//
// 이 함수에 의해 매핑되는 문자열은 multibyte character set으로 부터 반드시 유래하는 건 아니다.
//////////////////////////////////////////////////
int MultiByteToWideChar (
UINT CodePage, // code page
DWORD dwFlags, // character-type options
LPCSTR lpMultiByteStr, // string to map
int cbMultiByte, // number of bytes in string
LPWSTR lpWideCharStr, // wide-character buffer
int cchWideChar // size of buffer
);
CodePage :
[in] 변환 수행에 사용될 code page를 기술한다.
이 파라메타는 설치되거나 또는 시스템에 유효한 어떤한 코드페이지가 될수 있다.
또는 아래에 기술된 값중 하나를 기술할 수 있다.

CP_ACP : ANSI 코드 페이지
CP_MACCP : Macintosh 코드 페이지
CP_OEMCP : OEB 코드 페이지

lpMultiByteStr :
[in] 변환 되어질 문자열 스트링 포인터

cbMultiByte
[in] lpMultiByteStr 파라메타에 의해 포인트된 문자열의 바이트 사이즈
lpWideCharStr
[out] 변환된 문자열을 수신할 버퍼 포인터
cchWideChar
[in] wide character로, lpWideCharStr파라메타에 의해 포인트된 버퍼의 크기
만약 이값이 0이면, 이함수는 wide character로 요구되어진 buffer size를 반환한다,
그리고 lpWideCharStr 버퍼의 사용을 하지 않는다.
Return Values

If the function succeeds, and cchWideChar is nonzero, the return value is the number of wide characters written to the buffer pointed to by lpWideCharStr.
If the function succeeds, and cchWideChar is zero, the return value is the required size, in wide characters, for a buffer that can receive the translated string.
If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:
ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER
ERROR_NO_UNICODE_TRANSLATION
▷ASCII ==> UNICODE 변환방법
// sTime이란 ANSI 무낮열을 bstr이란 이름의 유니코드(BSTR타입) 변수로 변환
char sTime[] = '유니코드 변환 예제';
BSTR bstr;
// sTime을 유니코드로 변환하기에 앞서 먼저 그것의 유니코드에서의 길이를 알아야 한다.
int nLen = MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), NULL, NULL)
// 얻어낸 길이만큼 메모리를 할당한다.
bstr = SysAllocStringLen(NULL, nLen);
// 이제 변환을 수행한다.
MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), bstr, nLen);
▷UNICODE ==> ASCII 변환방법
// newVal이란 BSTR 타입에 있는 유니코드 문자열을 sTime이라는 ANSI 문자열로 변환
char sTime[128];
WideCharToMultiByte(CP_ACP, 0, newVal, -1, sTime, 127/*원래크기보다 1작게*/, NULL, NULL);

===================================================
● 코드 페이지를 이용하여 조합/완성/유니코드를 주무르자.
====================================================
윈도우즈 API에서 MultiByteToWideChar와 WideCharToMultiByte를 이용하면 완성,
조합에서 유니코드로 혹은 그 반대로 변환을 할 수 있습니다.
한글 95나 NT의 경우 기본적으로 조합형과 완성형의 코드페이지가 설치 되어있으므로 문제가 없으나
영문의 경우는 IE에서 한글 package를 설치하면 완성형은 설치가 되나 조합형은 없습니다.
코드페이지 설치.
'CP_XXX.nls'(WIN95) or 'C_XXX.nls'(WINNT)를 구하십시요. XXX 는 1361(조합) or 949(완성)입니다.
레지스트리에 다음의 값을 입력하십시요.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\XXX=CP_XXX.nls (WIN95)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\XXX=C_XXX.nls (WINNT)
조합형 코드를 보고자 할때는 cp_1361.nls(95용), c_1361.nls(nt용)을 구하셔서 시스템에 설치를 합니다.
95의 경우 system 디렉토리에, NT의 경우 system32 디렉토리에 설치하십시요.
=====================================================================
/*
* MultiByteToWideChar와 WideCharToMultiByte를 이용한 완성형, 조합형, 유니코드 변환.
*/
#include
#define CP_WANSUNG 949
#define CP_JOHAB 1361

void ConvertWansungToUnicode (LPCSTR szInput, int nInputSize, LPWSTR* szUnicode, int* nUnicodeSize)
{
// 유니코드의 크기를 구한다.
*nUnicodeSize = MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
NULL, 0);
*szUnicode = (LPWSTR)malloc(nUnicodeSize*sizeof(WCHAR));
// 실제 유니코드로 변환.
MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
*szUnicode, *nUnicodeSize);
}
void ConvertJohabToUnicode (LPCSTR szInput, int nInputSize, LPWSTR* szUnicode, int* nUnicodeSize)
{
// 유니코드의 크기를 구한다.
*nUnicodeSize = MultiByteToWideChar(CP_JOHAB, 0,
szInput, nInputSize,
NULL, 0);
*szUnicode = (LPWSTR)malloc(nUnicodeSize*sizeof(WCHAR));
// 실제 유니코드로 변환.
MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
*szUnicode, *nUnicodeSize);
}
void ConvertWansungToJohab (LPCSTR szInput, int nInputSize, LPSTR* szOutput, int* nOutputSize)
{
int nUnicodeSize;
LPWSTR szUnicode;
// 1. 완성형을 유니코드로 변환
// 유니코드의 크기를 구한다.
nUnicodeSize = MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
NULL, 0);
szUnicode = (LPWSTR)malloc(nUnicodeSize*sizeof(WCHAR));
// 실제 유니코드로 변환.
MultiByteToWideChar(CP_WANSUNG, 0,
szInput, nInputSize,
szUnicode, nUnicodeSize);
// 2. 유니코드를 조합형으로 변환.
// 조합형의 크기를 구한다.
*nOutputSize = WideCharToMultiByte(CP_JOHAB, 0,
szUnicode, nUnicodeSize,
NULL, 0, NULL,NULL);
*szOutput = (LPSTR)malloc(*nOutputSize);
// 실제 조합형으로 변환.
WideCharToMultiByte(CP_JOHAB, 0,
szUnicode, nUnicodeSize,
*szOutput, *nOutputSize, NULL,NULL);
free(szUnicode);
}
유니코드 문자열을 UTF8 문자열로 변환하는 방법

KB Article ID: K001368

--------------------------------------------------------------------------------

이 내용이 적용되는 제품:
- Platform SDK

[요 약]

한글 윈도우 95에서 유니코드 문자열을 UTF8 문자열로 변환해 주는 다음 함수를 실행하면, 리턴되는 UTF8 버퍼에 아무런 값도 리턴 되지 않습니다. RFC2044에 명시된 스펙에 의거하여 문자열 변환하는 방법을 소개합니다.

#include “winnls.h”
WideCharToMultiByte(CP_UTF8, 0, szUniBuf, nUniLen, szUTFBuf, sizeof(szUTFBuf), NULL, NULL);

[추가 정보]

한글 윈도우 95에서 WIN32 API인 WideCharToMultiByte(CP_UTF8, xxx) 함수에서 UTF8 버퍼에 아무런 값도 리턴하지 않으므로 다음과 같이 스펙에 의거한 변환 루틴을 이용하여 UTF8 문자열 값을 얻습니다.

char* UnicodeToUTF8(wchar_t uc, char* UTF8)
{
if (uc <= 0x7f)
{
UTF8[0] = (char) uc;
UTF8[1] = (char) '\0';
}
else if (uc <= 0x7ff)
{
UTF8[0] = (char) 0xc0 + uc / (wchar_t) pow(2, 6);
UTF8[1] = (char) 0x80 + uc % (wchar_t) pow(2, 6);
UTF8[2] = (char) '\0';
}
else if (uc <= 0xffff)
{
UTF8[0] = (char) 0xe0 + uc / (wchar_t) pow(2, 12);
UTF8[1] = (char) 0x80 + uc / (wchar_t) pow(2, 6) % (wchar_t) pow(2, 6);
UTF8[2] = (char) 0x80 + uc % (wchar_t) pow(2, 6);
UTF8[3] = (char) '\0';
}

return UTF8;
}

int WideStrToUTF8Str(wchar_t *szUni,char *szUTF8)
{
int i=0;
char TempUTF8[10];
for(i=0;szUni[i];i++) {
UnicodeToUTF8(szUni[i], TempUTF8);
strcat(szUTF8, TempUTF8);
}
return strlen(szUTF8);
}

실제 위 두 함수를 사용하는 예제

{
wchar_t szUniBuf[MAXBUF];
int nUniLen, nUTFLen;
char szUTFBuf[MAXBUF];

nUniLen = MultiByteToWideChar(CP_ACP, 0, szHello, strlen(szHello), szUniBuf, MAXBUF);
szUniBuf[nUniLen] = 0;
memset(szUTFBuf, 0, MAXBUF);
nUTFLen = WideStrToUTF8Str(szUniBuf, szUTFBuf);
//nUTFLen = WideCharToMultiByte(CP_UTF8, 0, szUniBuf, nUniLen, szUTFBuf, MAXBUF, NULL, NULL);
szUTFBuf[nUTFLen]=0x00;

}


한글 EBCIDIC 코드를 한글 ASCII 코드로 변환하는 방법

KB Article ID: K001143

--------------------------------------------------------------------------------

[요 약]

프로그래밍적으로, 한글 EBCIDIC 코드를 한글 ASCII 코드로 변환하는 방법을
여기에서 소개한다.

[추가 정보]

#include 'snanls.h'
function()
{
int ret;
LPCTSTR lpSrcStr, lpDestStr;
ret =SnaInit(CP_949);
printf('ret = %d', ret);
ret = SnaNlsMapString (lpSrcStr, lpDestStr, CP_933, CP_949, 2, 2,
SNA_MULTIBYTE, SNA_MULTIBYTE, 0x0);
printf('ret = %d', ret);
}


1. SnaInit(CP_949)는 현재 이 프로그램이 실행되는 환경의 코드 페이지를
지정한다.
2. lpSrcStr은 IBM 메인 프레임 컴퓨터 등으로부터 받은 한글 EBCIDIC 코드이며,
lpDestStr은 리턴되는 ASCII 코드값이다.
3. #define CP_933 933 /* EBCDIC Korean */
#define CP_949 949 /* Korean */
UTF-8 to Unicode / Unicode to UTF-8 transformation

Posted by SB패밀리

MFC에서 유니코드 버전으로 된 프로젝트에서 CString 를 char* 로 바꾸는 방법은
유니코드 상태에서 CString 을 바로 CHAR* 로 바꾸는 것이 안됩니다.

W2A 나 A2W 로 코드 변환을 하거나 wsprintf(); 함수를 이용 하면 됩니다.

유니코드는 사용 되는 바이트 수가 2바이트이고 1바이트 문자열로 변환하면 깨져 버리는 문자열 들이 있는데  처리를 해야 합니다.

유니코드를 멀티바이트 코드로 변환 하려면

char Text[80];
wsprintfA(Text, "%s", L"문자열" );

멀티바이트 코드를 유니코드로 변환 하려면

WCHAR Text[80];
wsprintfW(Text, L"%s", "문자열" );


변환될 문자열을 %s(대문자)로 wsprintf()함수를 사용합니다.

※ 현재로써는 바로 CString 에서 char*(LPSTR , LPCSTR) 로 변환 할수 없습니다.

참고로 더 설명을 하면 CString 기본 요소는 CStringBase<WCHAR>  , CStringBase<CHAR> 둘로 나누어집니다.
이 두 클래스 사이에서 바로 입력 변환이 불가능 합니다.

변환시에는 API 함수로 코드 변환 후에 사용 해야 하며 
CStringBase<CHAR> 로 사용 한다면 유니코드 내에서 ANSI 코드를 사용 할 수 있습니다.

또 다른 방법의 함수
-----------------------------
CString을 유니코드로

CString tmp("test");
WCHAR m_wPath[MAX_PATH];

wcscpy(wPath,tmp.GetBuffer(0));

Posted by SB패밀리

싱글바이트캐릭터
SBCS (Single-byte character set)
한 문자 표현에 1Byte를 사용하는 방식이다.
예로 ASCII 코드가 있으며, 한글이나 일본어표현은 불가능하다.


멀티바이트캐릭터
MBCS (Multi-byte character set)
한 문자 표현에 1Byte 이상을 사용하는 방식으로 Windows에서 MBCS에는 딱 두종류가 있다.
SBCS와 DBCS( Double-byte character set) 결국 많아봐야 최대 2Byte라는 얘기다.
한글이나 일본어가 처리되는 기본 방식이다.
즉,

printf( “안녕하삼” );
std::cout<<”배고프네”;
 

  이렇게 코드를 작성하고 컴파일해서 실행했을 때, 이게 바로 MBCS를 사용한 것이 된다.

유니코드
Unicode (wide characters)
유니코드는 모든캐릭터들을 2Byte로 표현하는 표준 Encoding 방식이다.
즉 구조적으로 한 글자가 1Byte, 2Byte, 3Byte 어느것이든 가능한 MBSC와 구분된다.


> C++에서 종료 문자열
SBCS/MBCS
코드상 별도의 구분없이 사용하므로, 기본 C-Style 문자열에서 처럼 ‘\0’ 한번
즉, 0Byte 값이 문자열의 끝을 표현.

Unicode
모든 캐릭터를 2Byte로 Encoding 하므로, 종료 문자열도 ‘\0’이 두번 위치.
즉, 0Byte 2개가 문자열의 끝을 표현.



> Data type
SBCS/MBCS
char : 일반적인 1Byte 문자형 char를 사용해서 표현

Unicode
wchar_t : wide-character 타입 문자형을 사용하며, 값 지정시 prefix L 을 사용한다.
wchar_t wch = L’즐’; //2Bytes
wchar_t* wstr = L”Hi”; // 6Bytes



> 문자열 처리 함수
SBCS
strcpy(), sprintf(), atol()등의 함수

MBCS
_mbscpy()처럼 _mbsXXX()식으로 이름이 붙은 mbcs전용 함수를 사용해야 한다.

Unicode
wcsXXX()식의 함수나 swprintf(), _wtol()처럼 앞에 w등이 붙은 unicode전용 함수를 사용해야 한다.
Posted by SB패밀리

sql server 2000에서 sp_executesql 을 사용할 때 제약조건이 있었는데,

sql 문을 4000자 이상 처리할 수 없다는 것입니다.

sql 문은 유니코드 문자열(nvarchar 나 nchar)이어야 하기 때문에 최대 4000자까지 쓸 수 있습니다.
참고로 ntext 형은 변수 선언을 할 수 없습니다.

 

예를 들어 다음과 같은 쿼리가 있다고 해보죠.

declare @sql nvarchar(4000)
set @sql = 'select * from tableA .....' 
exec dbo.sp_executesql @sql

 

만약 @sql에 4000자가 넘어가는 문장을 넣게되면 @sql은 4000자에서 문장을 자를것이고, 따라서 sp_executesql은 실패하게 될 것입니다.

 

하지만 sql server 2005에서는 nvarchar(max)라를 데이터 타입이 추가되었고,

변수 선언이 가능해 졌습니다.

다음과 같이 위 쿼리를 수정하면 sql server 2005에서는 4000자 이상되는

동적 쿼리도 처리가 가능해 집니다.

declare @sql nvarchar(max)
set @sql = 'select * from tableA .....' 
exec dbo.sp_executesql @sql 

Posted by SB패밀리