2장 MBCS와 WBCS의 동시 지원

Yama·2023년 12월 18일

MBCS와 WBCS의 동시 지원

  • 프로그램의 구현에 있어서 MBCS 기반으로 할것이냐 WBCS기반으로 할것이냐는 매우 골치 아픈일.
    • WBCS기반으로 하면 구현하면 여러모로 좋겠지만 현존하는 모든 시스템 모두가 완벽히 유니코드 기반을 지원하는것이 아니다.(아직도?)
  • 문제점
    • MBCS, WBCS 나눠서 구현하는것은 매우 귀찮은 일이다.
      1. 문자열 앞에 문자 'L'도 붙여 줘야한다.
      2. 사용되는 문자열 관련 함수들도 모두 변경해줘야 한다.
      3. 유지보수도 힘듬.
  • 해결법
    • 프로그램은 한번만 구현하고, 별다른 변경 없이 MBCS 기반으로 돌아가는 형태로도, WBCS 기반으로 돌아가는 형태로도 컴파일 가능하다면 될듯?

#include <'windows.h>

  • windows.h는 Windows 기반 프로그래밍 하는데 있어서 기본적으로 항상 포함되는 헤더 파일.
    • Windows 프로그래밍에 필요한 다양한 종류의 헤더파일을 더불어 포함하기 떄문에 이 헤더파일 하나로 충분경우 대부분
    • windows.h <- windef.h <- winnt.h(CHAR, WCHAR)
  • Windows 시스템 프로그래밍에 필요한 대부분의 것을 직접 / 간접적으로 포함하게 된다는 것만 알면됨.
    • 정의되어 있는 파일 무엇인지?
    • 어떠한 경로를 통해서 windows.h에 포함되는지 공부하는 것도 굿.

Windows에서 정의하고 잇는 자료형

  • typedef 키워드롤 통해서 몇몇 기본 자료형에 Windows 스타일의 새로운 이름을 정의한다.
    • 양이 많다.
  • Windows 스타일의 CHAR, WCHAR 정의
  • 문자열 주소값을 저장하는 Windows 스타일 자료형
  • 두번째 줄을 보면 CHAR가 LPSTR로 정의되어 있음을 알수 있다. 그런데 CHAR은 char로 정의되어 있으므로, 결국 LPSTR은 우리가 아는 char을 의미한다.

Windows 스타일 자료형에 대한 이야기

  • Windows 스타일의 이름으로 자료형을 정의하는 이유?
    1. 선언의 편리성
    2. 확장의 용이성
  • typedf 기반으로 적절한 이름의 자료형을 정의하는 것은 아주 좋은 프로그래밍 습관이다.

WinString.cpp

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

// 속성 -> 고급 -> 컴파일 옵션 C언어로 변경해야 오류 안난다.

int wmain(int argc, wchar_t* argv[])
{
    LPSTR str1 = "SBCS Style String 1";
    LPWSTR str2 = L"WBCS Style String 1";

    CHAR arr1[] = "SBCS Style String 2";
    WCHAR  arr2[] = L"WBCS S tyle String 2";

    LPCSTR cStr1 = arr1;
    LPCWSTR cStr2 = arr2;

    printf("%s\n", str1);
    printf("%s\n", arr1);

    wprintf(L"%s\n", str2);
    wprintf(L"%s\n", arr2);

    return 0;
}

MBCS와 WBCS(유니코드)를 동시에 지원하기 위한 매크로

  • 보기전에 매크로 복습하시오.
  • 헤더파일 tchar.h에 선언되어 잇는것을 보기좋게 편집한것.
  • tchar.h는 windows.h에 포함되지 않는다.
    • tchar.h를 추가로 포함 시켜야 한다.
	TCHAR arr[10];
  • 만약에 UNICODE 라는 매크로가 정의되어 있지 않다면, 이 배열 선언은 전처리기에 의해서 변경된다.
	CHAR arr[10];
  • UNICODE 매크로 있으면
	WCHAR arr[10];
  • 예시 추가

	_T("HANBIT");
  • 이 매크로는 아무 조건 없이
	__T("HANBIT");
  • _UNICODE 라는 매크로가 정의 있지 않다면, MBCS타입의 문자열로 변경
	"HANBIT";
  • _UNICODE 라는 매크로 정의 되어 있다면 전처리기에 의해서 WBCS기반의 문자열로 변경
	L"HANBIT";

MBCS_WBCS1.cpp

#define UNICODE // 1
#define _UNICODE // 2
//#undef UNICODE // 3
//#undef _UNICODE // 4

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

int wmain()
{
	TCHAR str[] = _T("1234567"); 
	int size = sizeof(str);
	printf("string lenght : %d \n", size);
	return 0;
}

  • 유니코드와 MBCS를 동시에 지원하는 프로그램의 예(// 1 뺴고)
  • 매크로 UNICODE와 _UNICODE 가 정의 되었으니, TCHAR은 "wchar_t"로 _T("1234567") -> L("1234567") 인식된다.
  • 매크로 UNICODE와 _UNICODE는 헤더파일 선언 이전에 등장해야 한다.
    • 정의된 매크로에 따라서 헤더파일에 선언된 자료형의 형태가 결정되기 때문이다. 만약에 헤더파일 선언 이후에 등장하게 되면, 아무런 효과가 없게 된다.
  • // 1,2를 주석처리해서 전처리기 속성 변경하거나
  • // 3,4를 추가하면 저렇게 나온다.

MBCS와 WBCS(유니코드)를 동시에 지원하기 위한 함수들

  • MBCS_WBCS1.cpp는 매크로 UNICODE와 _UNICODE의 정의 유무에 따라서 WBCS 기반, 혹은 MBCS 기반으로 컴파일 및 실행이 된다.
  • BUT 아직 완벽하지 않음
	printf("string lenght : %d \n", size);
  • 매크로 정의에 상관없이 MBCS기반으로 컴파일 된다.
	wprintf(L"string lenght : %d \n", size);
  • 유니코드 기반으로 완벽히 돌아간다
  • 매크로 UNICODE와 _UNICODE의 정의 유무에 따라서 WBCS 기반 혹은 MBCS로 컴파일 하고자 할려면?
  • 매크로 _T("string")을 이용
	_tprintf(_T"string lenght : %d \n", size);
  • 정의 유무에 따라서 이렇게 컴파일 된다.
    • tchar.h에 선언되어있는 함수 이름과 매크로(많이 쓰는)

MBCS_WBCS2.cpp

#define UNICODE
#define _UNICODE

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

int _tmain(int arhc, TCHAR* argvp[])
{
	LPTSTR str1 = _T("MBCS or WBCS 1");
	TCHAR str2 = _T("MBCS or WBCS 2");
	TCHAR str3[100];
	TCHAR str4[50];

	LPCTSTR pStr = str1;

	_tprintf(_T("string size: %d \n"), sizeof(str2));
	_tprintf(_T("string lenght: %d \n"), _tcslen(pStr));

	_fputts(_T("Input String 1 : "), stdout);
	_tscanf(_T("%s"), str3);
	_fputts(_T("Input String 2 : "), stdout);
	_tscanf(_T("%s"), str4);

	_tcscat(str3, str4);
	_tprintf(_T("String1 + String2 : %s \n"), str3);

	return 0;
}
  • 실행이 안된다 아ㅏㅏㅏㅏㅏ.
  • 올바른 실행 결과

1차 23.12.18
2차 23.12.19
3차 23.12.20
4차 23.12.21
5차 23.12.22
6차 23.12.26
7차 24.01.02

0개의 댓글