C언어에서 문자열 분리 문제...

toold의 이미지

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

kane의 이미지

대략적인 아이디어는 0x80으로 시작할때는 한글로 가정하여 2byte씩 잘라내고,
아닐때는 영어로 가정하여 1byte씩 잘라냅니다.

자세한 사항은 글자 인코딩 관련 지식이 있으신 분들이 잘 아실 것 같습니다만...

참고로 php쪽에서도 비슷한 방법을 사용할 겁니다. 그 쪽 분들께 물어보시는 것도 좋을 것 같네요.

nahanjang의 이미지

이런 함수는 어떨까요?...

$> 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

nahanjang의 이미지

그러고 보니 한글일때는 구분이 안가는하군요...
iscntrl()과 조합하면 사용이 가능할려나...
퍽 ~ 별도움이 못되는거 같군요..

dictions의 이미지

#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 )


----------------------------------------------------------------------------

eungkyu의 이미지

이 정도로 하면 되지 않을까요

#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;
}
정태영의 이미지

kane wrote:
대략적인 아이디어는 0x80으로 시작할때는 한글로 가정하여 2byte씩 잘라내고,
아닐때는 영어로 가정하여 1byte씩 잘라냅니다.

자세한 사항은 글자 인코딩 관련 지식이 있으신 분들이 잘 아실 것 같습니다만...

참고로 php쪽에서도 비슷한 방법을 사용할 겁니다. 그 쪽 분들께 물어보시는 것도 좋을 것 같네요.

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 ~(~_~)~
나 한줄기 바람처럼..

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.