본문 바로가기

C, C++/WINDOWS VIA C,C++

[WINDOWS VIA C/C++] 02.문자와 문자열로 작업하기

https://www.hanbit.co.kr/store/books/look.php?p_code=B2974835990

 

제프리 리처의 Windows via C/C++(복간판)

이 책은 윈도우 XP, 윈도우 비스타, 윈도우 서버 2008까지 내용을 포괄한다. 이미 윈도우 10이 출시된 지 오래지만 윈도우의 기본 구조는 변하지 않아 아직까지도 이 책은 윈도우 시스템 프로그래

www.hanbit.co.kr

해당 책을 읽고 학습 목적으로 간단하게 정리한 글입니다.


Chapter 02: 문자와 문자열로 작업하기

개요

이번 챕터에서는 다국어 개발을 위한 유니코드와 버퍼 오버런을 막기 위한 안전 문자열 함수에 대해서 알아본다.


문자 인코딩

https://basaeng.tistory.com/3

 

컴퓨터로 문자를 표현하는 법

개요컴퓨터는 언제나 0과 1만 인식할 수 있다. 모든 문자는 이진수로 변환되어 저장되고 이진수가 다시 문자로 변환되어 우리에게 보이게 된다. 이 과정을 문자 인코딩, 문자 디코딩이라고 한

basaeng.tistory.com

UTF-8은 하나의 문자를 위해 1, 2, 3, 4바이트로 인코딩을 수행한다. 0x800이상의 문자가 많이 사용된다면 비효율적이다. 

UTF-16은 모든 문자를 2바이트로 인코딩한다. 바이트가 같기 때문에 코딩에 용이하다.


유니코드 문자, 문자열 자료형

유니코드 문자열은 

wchar_t szBuffer[] = L"Hello";

와 같이 앞에 대문자 L을 붙여 유니코드임을 명시해야 한다.

 

그리고 프로그램에 UNICODE가 define되어있으면 유니코드 문자로 취급하고 없다면 일반(아스키)문자로 취급하는 tchar 자료형이 있다.

일반적으로 생성되는 vs 프로그램에는 기본적으로 전처리기에 UNICODE가 등록된다.


윈도우 내의 유니코드, ANSI 함수

윈도우 NT 이후 함수들은 유니코드 문자열을 요구한다.

ANSI문자열을 전달한다면 문자열을 유니코드로 변경하고 이를 전달하며, ANSI문자열이 반환된다면 유니코드를 ANSI로 변환하는 과정이 들어간다.

 

따라서 기본적으로 유니코드 함수를 사용하는 편이 낫다.

 

윈도우 함수에서 유니코드를 구별하는 방식은 함수 이름뒤에 W, A를 붙이는 것이다. W는 Wide Character를 사용하는 유니코드 함수임을 뜻하며, A는 ANSI Character를 사용하는 함수임을 뜻한다.


C런타임 라이브러리 내의 유니코드, ANSI 함수

윈도우와 같이 C런타임 라이브러리도 유니코드, ANSI를 다루는 함수가 별도로 존재한다.

 

strlen, strcpy등 함수는 wcslen, wcscpy 같은 함수에 대응된다.

중립적인 _tcslen같은 함수들도 존재한다.

 

"책에서는 가능한 중립적인 함수를 사용하는 것을 권장하지만 처음부터 유니코드를 사용하는 프로그램을 만드는 것이 낫겠다"


C런타임 라이브러리 내의 안전 문자열 함수

C런타임 라이브러리의 문자열 함수는 버퍼 오버런 문제에 취약하다.

https://ko.wikipedia.org/wiki/%EB%B2%84%ED%8D%BC_%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C

 

버퍼 오버플로 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 다른 뜻에 대해서는 오버플로 문서를 참고하십시오. 소프트웨어 버퍼 오버플로 시각화. 데이터가 A에 기록되지만 너무 커서 A에 맞지 않아 B로 오버플로된다.

ko.wikipedia.org

따라서 최근 윈도우는 안전 문자열 함수를 권장하며 일반 문자열 함수를 사용했을 때 컴파일도 되지않는다.(ignore 시킨다면 가능)

 

StrSafe.h헤더 파일을 포함하면 사용할 수 있다.

https://learn.microsoft.com/ko-kr/cpp/c-runtime-library/reference/strcpy-wcscpy-mbscpy?view=msvc-170

 

strcpy, wcscpy, _mbscpy

자세한 정보: strcpy, wcscpy, _mbscpy

learn.microsoft.com

 

https://learn.microsoft.com/ko-kr/cpp/c-runtime-library/reference/strcpy-s-wcscpy-s-mbscpy-s?view=msvc-170

 

strcpy_s, wcscpy_s, _mbscpy_s, _mbscpy_s_l

자세한 정보: strcpy_s, wcscpy_s, _mbscpy_s, _mbscpy_s_l

learn.microsoft.com

안전문자열 함수에는 추가적으로 버퍼의 크기가 전달된다. 해당 값으로는 문자의 개수를 전달한다.

_countof 매크로를 통해 편하게 구할 수 있다.

 

_s로 끝나는 안전 문자열 함수는 버퍼 오버런이 발생하는 상황이면 일부만 성공하는 것이 아닌 전체가 실패하고 원본또한 에러 값으로 바뀔 수 있다.

 

StringCch(Count of characters)계열 함수는 버퍼 오버런이 발생할 수 있다면, 가능한 만큼만 사용되는 문자열 잘림이 수행된다.

그리고 각 경우에 대한 HRESULT값을 반환한다.

https://learn.microsoft.com/ko-kr/windows/win32/api/strsafe/nf-strsafe-stringcchcopyw 

 

StringCchCopyW 함수(strsafe.h) - Win32 apps

한 문자열을 다른 문자열에 복사합니다. (StringCchCopyW)

learn.microsoft.com

S_OK: 정상 성공

STRSAFE_E_INVALID_PARAMETER: 인자가 NULL임

STRSAFE_E_INSUFFICIENT_BUFFER: 버퍼의 크기가 충분하지 않음

 

추가적으로 Ex함수들은 확장 파라미터를 받는다.


애플리케이션 개발 시 반드시 유니코드를 사용하자.

 

유니코드와 ANSI 문자열 사이의 변경이 필요하다면 MultiByteToWideChar, WideCharToMultiByte함수를 사용한다.