학습자료(~2017)/C,C++

유니코드(unicode) 관련 함수

단세포소년 2011. 11. 17. 19:48
반응형


학교에서 배울때는 멀티바이트코드 즉 char 형으로만 프로그램을 작성하였다.
하지만 요즘은 유니코드로 프로그램을 작성하지 않으면 호환성면에서 크게 떨어진다는 것을 느꼇다.
왜 학교에서는 유니코드 관련해서 가르쳐주지 않는지..

유니코드 관련 함수는 추가적으로 계속 업데이트 할 것이다. 밑에 내용들은 함수 이름만 표현할 것이다.
내용은 참고 사이트나 google에 검색해보기바란다. 멀티바이트와 매칭되는 유니코드 함수는 아래의 표현 예로 표현 할 것이다.
표현 예) 멀티바이트함수 -> 유니코드함수


0. 문자열 관련
char *str = "test";   ->   wchar_t *str = L"test";
문자열 앞에 'L' 을 붙여야 이것이 유니코드 즉 한문자당 2바이트를 할당받는지 컴파일러는 안다.



1. 파일 오픈
fopen -> _wfopen
예) FILE *file = _wfopen( L"_wfopen_test.xml",L"wt+,ccs=UNICODE"))
_wfopen 은 wchar_t 를 매개변수로 갖는다. 'ccs=UNICODE' 는 오픈하려는 파일이 유니코드로 인코딩 되었다는 것을 명시하여준 것이다. 만약 파일이 UTF-8 로 인코딩 되었다면 'ccs=UTF-8' 로 써넣으면 된다.
참고 : http://msdn.microsoft.com/en-us/library/yeby3zcb(v=vs.80).aspx



2.파일 한문자 읽기
fgetc -> fgetwc
예)
while(fgetwc(file)!=WEOF)
{
}
주의할 사항은 파일의 끝이 EOF 이 아니라 WEOF 이라는 점이다. EOF 은 -1로 정의되어 있고 WEOF 은 (unsigned short)0xfffff 이라는 것이다. fgetwc가 반환형이 unsigned short이므로 만약 EOF 와 비교를 하게된다면 0xffff 와 0xffffffff 를 비교하게 되는 것이다. 0xffff는 0xffffffff 와 비교되기 위해서 4바이트 int 형으로 바뀐다. 0x0000ffff 로 바뀐다는 것이다. 근데 의하한게 있을 것이다. 2바이트형이 4바이트형으로 변할때는 MSB(최대 비트값)값이 커지는 만큼 커진다고 배웠을 것이다. 즉 0xffffffff 이걸로 변한다고 했는데 왜 0x0000ffff로 변할까? 이유는 0xffff가  unsigned short 형이기 때문이다. unsigned 형은 크기가 커져야할때 커진만큼 비트에 0을 얻는다. (이유는 값이 음수가 되는것을 막기위해서다)
참고 : http://msdn.microsoft.com/en-us/library/c7sskzc1(v=vs.71).aspx



3.파일에 한문자 쓰기
fputc -> fputwc
참고 : http://msdn.microsoft.com/en-us/library/yah67377(v=vs.80).aspx



4.문자열 관련 함수
str 을 wcs 로 치환하여 생각하면 된다.
예) strcpy -> wcscpy, strcat -> wcscat 등등
일반적으로 알고 있는 문자열 관련 함수의 str을 wcs로 바꾸면 유니코드를 지원하는 함수이다.
문자열 관련 멀티바이트함수는 http://winapi.co.kr/clec/reference/reference.htm 이곳에서 알아보고 str을 wcs로 치환해서 유니코드 환경에 적용하도록..



5. \r\n 와 \n 윈도우와 리눅스간에 텍스트문서 교환시 발생하는 문제점(개행문자 문제)
개행문자은 윈도우와 리눅스가 다르다. 윈도우의 개행문자는 \r\n 2바이트이고 리눅스의 개행문자는 \n 1바이트이다.
그래서 발생하는 문제는 리눅스 텍스트문서를 윈도우로 가져왔을때 개행문자를 인식하지 못한다는 것이다.
(이런 경험들 많이 있을 것이다.) 프로그래머 입장에서 생각해보면 "그럼 윈도우에서 텍스트 문서 관련 코딩시 개행문자를 알기위해서는 \r\n 이 둘을 확인해야 된다는 것인가???" 라는 것이다. 
하지만 고민할 필요 없다. fopen 할때 바이너리모드가 아닌 텍스트모드로 문서를 열게되면 \r\n을 알아서 한바이트 \n로 치환해서 준다. 즉 \r 에 대해서는 전혀신경쓰지 않아도 된다는 말이다.

아래의 코드를 실험해보아라.
fopen("test.txt","r") 이것은 텍스트모드로 문서를 연 것이고 fopen("test.txt","rb")는 바이너리모드로 문서를 연 것이다.

예제코드1)
FILE *file = fopen("ReadMe.txt","rb");
 int c;
 while((c=fgetc(file))!=EOF)
 {
  if(c=='\r')
  printf("ㅋㅋㅋ");
 }

예제코드2)
FILE *file = fopen("ReadMe.txt","rt");
int c;
while((c=fgetc(file))!=EOF)
{
if(c=='\r')
printf("ㅋㅋㅋ");
}

[예제코드1]에서는 바이너리모드("rb")로 문서를 열었기 때문에 \r을 인식한다. 하지만
[예제코드2]에서는 텍스트모드("rt")로 문서를 열었기 때문에 \r을 인식하지 못한다.
내 생각에는 텍스트모드로 문서를 열면 내부적으로 \r 을 무시하고 넘어가는듯하다.
결론적으로 "텍스트모드로 문서를 열면 \r을 무시한다" 라고 생각하면 된다^^

보충 설명으로 fputc('\n',file) 을 하게된다면 이 함수는 자동으로 \r\n 을 입력할 것이다. 아~ 물론 파일이 텍스트모드로 열렸을 경우에만 이다..

반응형