오늘은 학생이 c언어에서 문자열이 입력 되었을때...
영문자 이거나 한글에서 맨 앞의 한글자만 출력해야 하는데 어떻게 하는지 묻길래 C언어에서 한글인지 영문인지 체크하는 방법을 알아 볼까 합니다.
먼저 다음과 같이
char Kor[] = "한글";
char Eng[]="English";
과 같이 변수를 선언하면서 데이터를 입력하면
먼저 strlen(Kor) 을 출력해 보면 4 또는 6이 나오는 것을 확인하실 수가 있는데요.
이것은 컴파일러마다 조금씩 다르기는 하지만 한글 같은 경우 2byte 혹은 3바이트를 사용하기 때문입니다.
그렇다면 Kor[0] 을 출력하면 당연히 "한" 이라는 글자는 출력 되지 않을 것입니다.
먼저 이러한 원리를 이해하기 위해서는 ASCII 코드를 이해 해야 되는데요.
이미지 출처 - http://shaeod.tistory.com/228
1Byte 로 저장할 수 있는 값은 8비트이므로 0x00(0) ~ 0xFF(255) 까지 입니다.
0부터 255 중에서 우리가 출력이 가능한 수는 일반적으로 0x20(32) ~ 0x7F(127) 까지 사용하고 있구요,
영문자 A~Z 까지는 0x41(65)~0x5A(90) a~z는 0x61(97)~0x7A(122) 까지를 사용하는 것을 알 수 있습니다.
따라서 한글이나 한문,일본어와 같은 경우는 당연히 1byte 가지고 처리가 안됩니다.
따라서 한글과 같은 경우는 2byte 혹은 3byte 로 처리를 하게 되는데요.
윈도우 내부적으로 사용하는 유니코드(UTF-16) 에서 2바이트로 사용을 하기 때문에 일단 2바이트를 가지고 설명을 하겠습니다.
먼저 UTF-16은 16비트 기반으로 문자열을 저장합니다. 기본 다국어 평면에 속하는 문자들은 16비드 값으로 인코딩 되고 그 이상의 문자는 특별히 정해진 방식으로 32비트로 인코딩 됩니다.
한글은 16비트로 사용 가능하며 유니코드 테이블 값을 확인해 보면 한글은 다음과 같습니다.
출처- https://en.wikipedia.org/wiki/Hangul_Syllables
테이블을 확인해 보면 0xAC00~0xD7A3 까지 한글을 사용하는 것을 확인해 볼수가 있습니다.
이것을 이진수로 변환해 보면 1010110000000000 ~ 1101011110100011 인것을 확인할 수 있습니다.
이때 앞의 8비트만 확인해 보면
10101100 ~ 11010111 인것을 확인 할 수가 있는데요.
우리가 사용하는 일반 알파벳은 0x20~0x7F 까지 사용한다고 하더라도
00100000 ~ 01111111 인 것을 확인할 수가 있습니다.
따라서 첫번째 비트가 1 로 시작하면 한글이고 0으로 시작하면 일반 Ascii 값이라는것을 판단 할 수가 있는데요.
이렇게 한바이트의 맨 처음 비트가 1인지 0 인지를 판단 하기 위해서는 0x80( 이진수로 변환하면 10000000) 을 비트연산 중 & 연산하여 0 이 나오는지 아닌지로 판단하면 됩니다.
따라서 위의 예에서
if(Kor[0] & 0x80) 를 하면 참이 나오고
if(Eng[0] & 0x80) 을 하면 거짓이 나옵니다.
따라서 어떤 문자열의 처음 한자리가 영문인지 한글인지 판단하여 처음 한자리만 출력 하는 것은 다음과 같이 판단하면 될것 같네요.
char str[1000];
scanf("%s",str);
if(str[0] & 0x80)
{
//한글이므로 두바이트를 출력해 주어야 한다.
printf("%c%c",str[0],str[1]);
}
else
{
//일반 Ascii 값으로 한바이트만 출력 하면 된다.
printf("%c", str[0]);
}
'강의자료 > 텍스트기반SW' 카테고리의 다른 글
구글 바드 API 파이썬에서 사용하기 (18) | 2023.06.28 |
---|---|
별찍기 원리에 대해 알아 봅니다. (9) | 2018.10.10 |
코드블럭(Code Block) 자동완성 기능 설정 (5) | 2018.08.22 |
코드블럭에서 can't find compiler executable in your search path (GNU GCC compiler) 에러 발생시 (9) | 2018.05.03 |
학생이 파이썬으로 만든 지뢰찾기 게임을 분석해 봅니다. (6) | 2018.01.31 |