C언어에서 문자열 분리 문제...
글쓴이: toold / 작성시간: 월, 2005/06/20 - 10:41오후
C언어에서..
"이곳은 school입니다"
라는 문자열이 있을 때
각 문자별로 분리하고 싶은데요..
즉,
'이'.'곳'.'은'.'s'.'c'.'h'.'o'.'o'.'l'.'입'.'니'.'다'
이렇게요..
근데 한글을 2byte고 영어는 1byte라서...
포인터 배열에다가 넣고 싶거든요..
어떻게 하면 한글인지 영어인지 구분해서 한글을 2byte씩 잘라내고 영어는 1byte씩 잘라낼 수 있을까요..?
다른언어에서는 간단해 보였는데 C에서는 도무지 방도가 없네요... :(
Forums:


대략적인 아이디어는 0x80으로 시작할때는 한글로 가정하여 2byte씩
대략적인 아이디어는 0x80으로 시작할때는 한글로 가정하여 2byte씩 잘라내고,
아닐때는 영어로 가정하여 1byte씩 잘라냅니다.
자세한 사항은 글자 인코딩 관련 지식이 있으신 분들이 잘 아실 것 같습니다만...
참고로 php쪽에서도 비슷한 방법을 사용할 겁니다. 그 쪽 분들께 물어보시는 것도 좋을 것 같네요.
이런 함수는 어떨까요?...[code:1]$> man isa
이런 함수는 어떨까요?...
$> man isalpha ISALPHA(3) 리눅스 프로그래머 매뉴얼 ISALPHA(3) 이름 isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit - 문자 유형별 루틴들 사용법 #include <ctype.h> int isalnum (int c); int isalpha (int c); int isascii (int c); int isblank (int c); int iscntrl (int c); int isdigit (int c); int isgraph (int c); int islower (int c); int isprint (int c); int ispunct (int c); int isspace (int c); int isupper (int c); int isxdigit (int c); 설명 이 들 함수들은 unsigned char 나 EOF값을가져야만 하는 c가현 재 로케일에 따라 어떤 문자 종류에 들어 있는지를 검사한 다. isalnum() 알 파 벳 등 의 문자와 숫자를 검사한다.; 이 함수는 (isalpha(c) || isdigit(c)) 과 동일하다. isalpha() 알파벳 문자를 검사한다; 표준 "C" 로케일에서, (isup- per(c) || islower(c)) 과 동일하다. 몇몇 로케일에 서, isalpha() 가 참인 추가적인 문자들이 있다--대 문 자나 소문자도 아닌 문자들. isascii() c가 ASCII 문자 집합에 속하는 7-bit unsigned char 인 지를 검사한다. 이 함수는 BSD 확장이며 또한 SVID 확 장이다. isblank() blank 문자인지 검사한다.; 즉, 스페이스나 탭. 이 함 수는 GNU 확장이다. iscntrl() 제어 문자인지 검사한다. isdigit() 숫자(0-9)인지 검사한다. isgraph() 스페이스를 제외한 프린트 가능 문자인지 검사한다. islower() 소문자인지 검사한다. isprint() 스페이스를 포함한 프린트 가능 문자인지 검사한다. ispunct() 스페이스나 알파벳등 문자와 숫자가 아닌 프린트 가 능 문자인지 검사한다. isspace() white-space 문자를 검사한다. "C" 와 "POSIX" 로케일 에서, 여기에는: 스페이스, form-feed ('\f'), 뉴 라인 ('\n'), 캐리지 리턴 ('\r'), 수평 탭 ('\t'), 그리고 수직 탭 ('\v'). isupper() 대문자인지 검사한다. isxdigit() 16진수 숫자인지를 검사한다. 즉 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F. 반환값 리 턴 값은 만일 문자 c 가 테스트되는 종류이면 0이 아닌값이 그렇지 않으면 0 값을 반환한다. 호환 ANSI - C, BSD 4.3. isascii() 는 BSD 확장이며 또한 SVID 확 장이다. isblank() 는 GNU 확장이다. 주의 클래스에 속한 문자들의 세부사항은 현재 로케일에 의존한다. 예를 들어, isupper() 는 A를 인시하지 못한다.-- 기본 C 로케 일에서 대문자로써 umlaut 관련 항목 tolower(3), toupper(3), setlocale(3), ascii(7), locale(7) 역자 정강훈 <skyeyes@soback.kornet.net>, 2001년 2월 25일 GNU 1995년 9월 2일 1그러고 보니 한글일때는 구분이 안가는하군요...iscntrl()과 조
그러고 보니 한글일때는 구분이 안가는하군요...
iscntrl()과 조합하면 사용이 가능할려나...
퍽 ~ 별도움이 못되는거 같군요..
이렇게..
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <string.h> int main() { char *str = "이곳은 school입니다."; char *p = str; char d[3]; while( *p ) { memset( d, 0x00, sizeof(char) * 3); if( *p & 0x80 ) { memcpy( d, p, sizeof(char) * 2); p+=2; } else { memcpy( d, p, sizeof(char) * 1); p++; } printf("'%s'", d); if( *p ) putchar(','); } return 0; }if( c & 0x80 )
if( c & 0x80 )
----------------------------------------------------------------------------
이 정도로 하면 되지 않을까요[code:1]#include <
이 정도로 하면 되지 않을까요
#include <stdio.h> #include <wchar.h> #include <locale.h> int main () { setlocale (LC_ALL, ""); wchar_t ws[80]; fgetws (ws, sizeof (ws), stdin); size_t len = wcslen (ws); if (ws [len - 1] == L'\n') ws [--len] = L'\0'; int i; for (i = 0; i < len; i++) { putwchar (L'\''); putwchar (ws[i]); putwchar (L'\''); } return 0; }[quote="kane"]대략적인 아이디어는 0x80으로 시작할때는 한글
euc 라면... 저 얘기가 맞겠지만 :) 유니코드라면 얘기가 달라집니다..
ucs_2 라면 영어 한글 할거 없이 다 2바이트씩 자르면 되고... utf-8 이라면... 처음에 나오는 컨트롤 빗의 수를 센다음... 그만큼 잘라주면 됩니다...
예를 들어... 한글 '가' 는 유니코드로...
0xAC00 입니다...
2진수로 나타내게 되면
1010 1100 0000 0000 이 되고...
utf-8 로 인코딩하게 되면...
1110 1010 1011 0000 1000 0000 : 0xea b0 80 이 되는거죠..
볼드처리한 부분을 떼어내면 다시 ucs_2 로 돌아갈 수 있구요 ;) 저 볼드 부분이 유니코드를 utf-8 로 변환하는 방법입니다...
한글은 3바이트를 사용하는 영역이 분포되어 있기 때문에... 시작이 1110 입니다... 2바이트 영역이라면 1100 으로 시작하고 4바이트 영역이라면 1111 0000로 시작하겠죠 ;)
그리고 두번째 바이트부터는 시작부분의 상위 2비트를 10 으로 표시합니다... 이건 나중에 utf-8 validation 을 하는데 사용할 수 있습니다...
하튼.... asc ii 에서 정의 되지 않은 128~255 를 사용하는 euc 라면... 윗분 얘기가 맞겠지만... 유니코드 세상에선 그렇지 않다는 걸 얘기하고 싶었습니다 :)
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...
http://mytears.org ~(~_~)~
나 한줄기 바람처럼..
댓글 달기