모든 문자의 표현이 가능한 UTF-8이나 UTF-16으로 문자셋을 설정하는 것이 좋을 것 같습니다. 다른 문자셋 설정해서 사용하다가 자칫 문자 깨지는 경우가 발생할 수도 있으니까요. 가령 사용자 환경이 다른 문자셋을 사용하는 경우에요. 그리고 코드 변환하는 함수도 만드셔야 할 거에요.
그리고 문자를 표현하기 위해 특정 문자를 숫자에 대응시킨 것을 인코딩이라고 합니다. 그리고 한 나라의 문자를 표로 정리한 것을 코드 페이지라 하고요. 그런데 ascii나 ansi는 여러 나라의 문자를 담기에는 그 크기가 작기 때문에 iso10646과 유니코드 컨소시엄이 유니코드를 독자적으로 만들었죠. 서로 표준을 만들었기 때문에 두 개의 표준이 공존하고 있었습니다. 두 개의 표준은 표준이라할 수 없었죠. iso의 것은 2바이트였고 유니코드 컨소시엄은 4바이트로 여러 코드 페이지를 구성하였습니다. 4바이트가 보다 현실적인 대안이라 합의가 되어 iso의 표준이 유니코드 컨소시엄에 맞추어 가는 방향으로 표준이 정립되어 지금의 유니코드가 등장했습니다. 그리고 유니코드는 UTF라는 여러가지 변환형식의 인코딩으로 표현되기 시작됐습니다. utf8은 영어와 기호를 1바이트, 그리고 1바이트로 표현할 수 없는 다른 알파벳 문자를 2바이트, 그리고 한글 및 일어 등을 3바이트의 가변길이로 표현합니다. 그리고 추가되는 문자를 위해 4바이트를 모두 사용할 수도 있도록 했습니다. 이러한 4바이트의 utf16을 서로게이트라고 합니다. 그리고 윈도우에서는 이 서로게이트를 지원하죠. 또한 utf16은 유니코드를 2바이트 내지는 4바이트의 고정 길이로 표현합니다. 단 한자나 한글의 고어 등을 표현하기 위해 4바이트의 고정 길이(서로게이트의 경우)로 표현하는 경우도 있습니다. 그러니 제 수준이 어떻다 하며 수준이나 언급하는 저 한심한 작자는 유니코드가 모두 가변길이인 것으로 잘못 알고 있군요. 모르면서 상당히 유식한 척 하는 한심한 부류라 할 수 있죠. 그리고 마지막으로 utf32는 4바이트의 고정 길이로 모든 문자를 표현합니다. 그 외에도 utf1, utf7 등이 있습니다. 한글이 제대로 출력된 것은 연속으로 계속 출력이 되기 때문입니다. 만약
이와 같이 하면 문자가 깨질겁니다. 즉 길이 하나가 2바이트 이상인 상수를 전부 담지 못한다는 것이 char의 난점이죠. 연속으로 문자열을 모두 출력할 때는 상관이 없습니다. 당연히 깨지지 않겠죠. 정 문자열이 유니코드인지 궁금하시다면 '가'라는 한 문자를
unsigned int ch='가';
//라고 ch에 대입해서
cout< <ch;
라고 출력해보세요. 그리고 유니코드에서 '가'의 값을 찾아보셔서, 그것이 어떤 utf와 일치하는 지를 살펴보시면 어떤 utf인지를 알 수 있을 겁니다. 아마 제 예전 경험에 비추어서 님과 같은 의문이 들었을 때 한글이 utf8이었던 것으로 기억합니다. 그래도 본인이 직접 확인하면서 유니코드를 변환하는 방법도 익히실겸, 제 설명이 맞는지도 검증할겸 한 번 검색해서 찾아보세요.
setlocale(lc_all, ko_kr.UTF-8) 로 설정하고 해보세요. 보통 UTF-8이나 UTF-16입니다. UTF-8은 3바이트고, UTF-16은 4바이트입니다. ascii로 설정됐어도 출력하는데는 지장이 없을 수도 있지만 특정 문자열을 검색할 때 한글을 ascii상태에서 검색하는 것은 좋지 않은 방법입니다. 받은 문자열을 검색하시려면 설정을 저런 식으로 잡고 받는 것이 좋습니다.
utf8과 utf16은 가변길이 인코딩입니다. utf8은 3바이트고 utf16은 4바이트라고 누가 그러던가요? 한글에 한정한다 쳐도, utf16은 글자당 2바이트로 인코딩됩니다. 앞에 BOM 붙은걸 글자당 4바이트로 착각하셨나보네요. 잘 모르시면 답변 달기 전에 먼저 공부를 하세요. 잘못된 지식 퍼뜨리지 말고.
말 나온김에 한가지만 더 쓰려고요. 질문은 단순합니다. 자바가 특정한 인코딩으로 반환한 것(혹은 소스코드에 박힌 것)을 C 프로그램이 인코딩-중립적으로 그냥 출력한 것이고, 다른 분들은 다 그 얘길 하시고 있습니다.
그런데 setlocale을 써야 한다네요. 음.. 이건 문제를 더 복잡하게 만드는 거죠. setlocale()은 아무 때나 쓰는 게 아니고, 특히 서버에서 특정 로케일로 명시해서 고정하는 건 더더욱 주의해야 합니다. 왠만하면 그건 틀린 해법이고 십중팔구 자기가 예상치 못한 곳들에서 에러를 만들어내겠죠. 다들 자기가 직접 혹은 남들이 저래놓은 걸로 고생하신 적들 있지 않나요 ㅋ
라고 하셨을 때, 한글출력도 1바이트씩 출력이 됩니다. 다만 저 한글인 상수 "한글출력"은 strlen으로 출력한 값이 만약 12가 나오면 한글 한 문자를 3바이트로 할당했다 볼 수 있으므로 그 때는 utf-8 인코딩이라 할 수 있을 겁니다. 그리고 네트워크 상에서는 보통 utf-8로 전송하는 것으로 알고 있고요. 다만 저렇게 한글을 char 배열로 대입하게 되면 포인터 이동시 글자가 깨질 수 있습니다. 예컨대
printf("%c",str[1]);
이라고 하면 말입니다. 그래서 범용 문자에 대해서는 보통 와이트 캐릭터인 wchar_t 타입을 씁니다. 그런데 이것도 정확히는 모르겟지만 좀 문제가 있다고 하시더군요. iconv를 사용해보라는 권유를 받은 적이 있습니다. 알파벳권 언어가 아닌 문자에 대해 관심이 있으시다면 유니코드에 대해 알아보세요. 아스키와 유니코드 그리고 UTF
뭘 잘 못 알고 계시네요. 무엇을 가변길이라고 하는지 알고 전부를 가변길이라고 우기시나. 몰라도 너무 한참 모르네. 저게 모두 가변길이라고 우기는 저 무식함. utf-8은 1~3바이트, utf16은 2 또는 4바이트. 뭐가 가변길이라고? 분간을 못하는 초자. 이래서 자세한 내용을 모르고 지껄이는 익명하고는 상종을 말아아됩니다. 내용을 파고 들면 무엇을 가변인지 질문자님을 분간하실 수 있다고 생각합니다. 내용으로 한 번 들어가서 가변이란 무엇을 말하는 것인지 생각하며 보세요.
유니코드(utf-8, utf-16)으로 설정하시는 것이 좋습니다. 언어간 충돌이 발생하지 않죠. 그리고 유니코드 사용하려면 문자코드를 조작하는 함수를 만드셔야 할겁니다. 제가 예전에 문자코드 공부하다가 문자열이 유니코드로 제대로 출력되지 않길래 알아보니 유니코드가 저장되는 순서때문에 그렇더군요. 미묘한 차이가 있으니 그 차이를 잡아주면 됩니다.
ANSI군요
자바에서 보낸게 바로 읽혀지는 이유는 멀까요..
보통 UTF-8이나 UTF-16을 사용합니다.
모든 문자의 표현이 가능한 UTF-8이나 UTF-16으로 문자셋을 설정하는 것이 좋을 것 같습니다. 다른 문자셋 설정해서 사용하다가 자칫 문자 깨지는 경우가 발생할 수도 있으니까요. 가령 사용자 환경이 다른 문자셋을 사용하는 경우에요. 그리고 코드 변환하는 함수도 만드셔야 할 거에요.
아래글 참조해보세요.
http://kldp.org/node/143024#comment-604917
그리고 문자를 표현하기 위해 특정 문자를 숫자에 대응시킨 것을 인코딩이라고 합니다. 그리고 한 나라의 문자를 표로 정리한 것을 코드 페이지라 하고요. 그런데 ascii나 ansi는 여러 나라의 문자를 담기에는 그 크기가 작기 때문에 iso10646과 유니코드 컨소시엄이 유니코드를 독자적으로 만들었죠. 서로 표준을 만들었기 때문에 두 개의 표준이 공존하고 있었습니다. 두 개의 표준은 표준이라할 수 없었죠. iso의 것은 2바이트였고 유니코드 컨소시엄은 4바이트로 여러 코드 페이지를 구성하였습니다. 4바이트가 보다 현실적인 대안이라 합의가 되어 iso의 표준이 유니코드 컨소시엄에 맞추어 가는 방향으로 표준이 정립되어 지금의 유니코드가 등장했습니다. 그리고 유니코드는 UTF라는 여러가지 변환형식의 인코딩으로 표현되기 시작됐습니다. utf8은 영어와 기호를 1바이트, 그리고 1바이트로 표현할 수 없는 다른 알파벳 문자를 2바이트, 그리고 한글 및 일어 등을 3바이트의 가변길이로 표현합니다. 그리고 추가되는 문자를 위해 4바이트를 모두 사용할 수도 있도록 했습니다. 이러한 4바이트의 utf16을 서로게이트라고 합니다. 그리고 윈도우에서는 이 서로게이트를 지원하죠. 또한 utf16은 유니코드를 2바이트 내지는 4바이트의 고정 길이로 표현합니다. 단 한자나 한글의 고어 등을 표현하기 위해 4바이트의 고정 길이(서로게이트의 경우)로 표현하는 경우도 있습니다. 그러니 제 수준이 어떻다 하며 수준이나 언급하는 저 한심한 작자는 유니코드가 모두 가변길이인 것으로 잘못 알고 있군요. 모르면서 상당히 유식한 척 하는 한심한 부류라 할 수 있죠. 그리고 마지막으로 utf32는 4바이트의 고정 길이로 모든 문자를 표현합니다. 그 외에도 utf1, utf7 등이 있습니다. 한글이 제대로 출력된 것은 연속으로 계속 출력이 되기 때문입니다. 만약
이와 같이 하면 문자가 깨질겁니다. 즉 길이 하나가 2바이트 이상인 상수를 전부 담지 못한다는 것이 char의 난점이죠. 연속으로 문자열을 모두 출력할 때는 상관이 없습니다. 당연히 깨지지 않겠죠. 정 문자열이 유니코드인지 궁금하시다면 '가'라는 한 문자를
라고 출력해보세요. 그리고 유니코드에서 '가'의 값을 찾아보셔서, 그것이 어떤 utf와 일치하는 지를 살펴보시면 어떤 utf인지를 알 수 있을 겁니다. 아마 제 예전 경험에 비추어서 님과 같은 의문이 들었을 때 한글이 utf8이었던 것으로 기억합니다. 그래도 본인이 직접 확인하면서 유니코드를 변환하는 방법도 익히실겸, 제 설명이 맞는지도 검증할겸 한 번 검색해서 찾아보세요.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
그때는 아마 상수 앞에 l을 붙였던가 했던 것
그때는 아마 상수 앞에 l을 붙였던가 했던 것 같은데. 기억이 잘 나지 않는군요. 하여튼 l자도 한 번 붙여서 점검해보세요.
l'가'
그리고
'가'
이런 식으로요.
ko_kr.EUC_KR
setlocale(lc_all, ko_kr.UTF-8) 로 설정하고 해보세요. 보통 UTF-8이나 UTF-16입니다. UTF-8은 3바이트고, UTF-16은 4바이트입니다. ascii로 설정됐어도 출력하는데는 지장이 없을 수도 있지만 특정 문자열을 검색할 때 한글을 ascii상태에서 검색하는 것은 좋지 않은 방법입니다. 받은 문자열을 검색하시려면 설정을 저런 식으로 잡고 받는 것이 좋습니다.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
utf8과 utf16은 가변길이 인코딩입니다.
utf8과 utf16은 가변길이 인코딩입니다. utf8은 3바이트고 utf16은 4바이트라고 누가 그러던가요? 한글에 한정한다 쳐도, utf16은 글자당 2바이트로 인코딩됩니다. 앞에 BOM 붙은걸 글자당 4바이트로 착각하셨나보네요. 잘 모르시면 답변 달기 전에 먼저 공부를 하세요. 잘못된 지식 퍼뜨리지 말고.
아무리 쓴 사람이 tunecolor라지만 그런식으로
아무리 쓴 사람이 tunecolor라지만 그런식으로 말할 것 까진 없지 않나요...
자기 수준은 자기가 지켜야죠.
닉없는 사람은 사람이 아니라나..
그런 말이 있어요.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
네 무슨 말씀인지 잘 알겠습니다. 말 나온김에
네 무슨 말씀인지 잘 알겠습니다.
말 나온김에 한가지만 더 쓰려고요. 질문은 단순합니다. 자바가 특정한 인코딩으로 반환한 것(혹은 소스코드에 박힌 것)을 C 프로그램이 인코딩-중립적으로 그냥 출력한 것이고, 다른 분들은 다 그 얘길 하시고 있습니다.
그런데 setlocale을 써야 한다네요. 음.. 이건 문제를 더 복잡하게 만드는 거죠. setlocale()은 아무 때나 쓰는 게 아니고, 특히 서버에서 특정 로케일로 명시해서 고정하는 건 더더욱 주의해야 합니다. 왠만하면 그건 틀린 해법이고 십중팔구 자기가 예상치 못한 곳들에서 에러를 만들어내겠죠. 다들 자기가 직접 혹은 남들이 저래놓은 걸로 고생하신 적들 있지 않나요 ㅋ
setlocale
저게 컴파일과 관련있다는 사실도 부연해 설명해드리죠. 그리고 모르고 쓰면 고생좀 할 겁니다. 고생하신 적이 많았나보죠? 하수들은 이것 때문에 꽤나 고생합니다. ㅋ. 그쪽만 고생하시겠죠.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
char str[] =
라고 하셨을 때, 한글출력도 1바이트씩 출력이 됩니다. 다만 저 한글인 상수 "한글출력"은 strlen으로 출력한 값이 만약 12가 나오면 한글 한 문자를 3바이트로 할당했다 볼 수 있으므로 그 때는 utf-8 인코딩이라 할 수 있을 겁니다. 그리고 네트워크 상에서는 보통 utf-8로 전송하는 것으로 알고 있고요. 다만 저렇게 한글을 char 배열로 대입하게 되면 포인터 이동시 글자가 깨질 수 있습니다. 예컨대
printf("%c",str[1]);
이라고 하면 말입니다. 그래서 범용 문자에 대해서는 보통 와이트 캐릭터인 wchar_t 타입을 씁니다. 그런데 이것도 정확히는 모르겟지만 좀 문제가 있다고 하시더군요. iconv를 사용해보라는 권유를 받은 적이 있습니다. 알파벳권 언어가 아닌 문자에 대해 관심이 있으시다면 유니코드에 대해 알아보세요. 아스키와 유니코드 그리고 UTF
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
땡, 그쪽 틀렸습니다.
뭘 잘 못 알고 계시네요. 무엇을 가변길이라고 하는지 알고 전부를 가변길이라고 우기시나. 몰라도 너무 한참 모르네. 저게 모두 가변길이라고 우기는 저 무식함. utf-8은 1~3바이트, utf16은 2 또는 4바이트. 뭐가 가변길이라고? 분간을 못하는 초자. 이래서 자세한 내용을 모르고 지껄이는 익명하고는 상종을 말아아됩니다. 내용을 파고 들면 무엇을 가변인지 질문자님을 분간하실 수 있다고 생각합니다. 내용으로 한 번 들어가서 가변이란 무엇을 말하는 것인지 생각하며 보세요.
위에꺼 쓴사람 아무래도 t모 양반 같은데...
위에 위에 사람이 한 말에 틀린 점은 없습니다.
utf-8, utf-16모두 Variable-width encoding에 속합니다.
대체 '가변'의 뜻을 뭐라고 생각하시는건지 모르겠군요.
위에 위에 사람이 댁한테 좀 심하게 말한건 사실인데
댁이 자신도 모르는 부분에 대해서 잘못된 답변을 하고 있는 것도 사실입니다.
그리고 댁은 좀 그렇게 심한 소리 들을만한 사람입니다.
댁은 태도도 문제지만,
이해가 제대로 안된 내용에 대해 잘못된 용어와 개념으로 잘 아는 것처럼 떠드는게 더 문제에요.
https://kldp.org/node/143262
이거 올린거 댁이 맞죠?
지금 댁의 유니코드에 대한 이해는 매우 심각한 수준입니다.
답변 달고 어쩌고 할 상황이 전혀 아니에요.
겸손한 태도로 도움을 청하세요.
여기 답글 달고 있는 사람들, 다 자기 여가시간 쪼개서 답글 달아주고 있는 겁니다.
이 사람..
utf-16이 왜 가변길이 인코딩인지 아직도 모른다에 100원 겁니다.
가능한 범용 언어용으로 프로그램을 만드시려면
유니코드(utf-8, utf-16)으로 설정하시는 것이 좋습니다. 언어간 충돌이 발생하지 않죠. 그리고 유니코드 사용하려면 문자코드를 조작하는 함수를 만드셔야 할겁니다. 제가 예전에 문자코드 공부하다가 문자열이 유니코드로 제대로 출력되지 않길래 알아보니 유니코드가 저장되는 순서때문에 그렇더군요. 미묘한 차이가 있으니 그 차이를 잡아주면 됩니다.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
...
C 컴파일러는 (십중팔구) 한글 인코딩을 신경쓰지 않습니다. 그냥 소스 코드에 들어있는 문자열을 그대로 사용할 뿐입니다.
그러니까 "이때 출력되는 한글의 인코딩은 무엇인가요?"에 대한 답은 "C 소스 코드가 사용한 인코딩"이 되겠습니다.
* 마찬가지로 "정상적으로 출력이 된다"라는 상황은 십중팔구 C에서 받은 문자열을 그대로 출력했더니 터미널에서 마침 같은 인코딩을 사용중이었다는 말입니다. 그러니까 터미널에서 사용중인 인코딩을 확인해 보시면 되겠습니다.
?
cp949 입니다. 윗 분 말씀대로 소스 코드에 들어있는 문자열을 그대로 출력할 뿐입니다.
즉 저장하신 소스 코드를 Hexedit 로 보면 한글 부분에 저장되어 있는 Hex 값이 그대로 출력됩니다.
자바에서 string.getBytes()로 바이트열을
자바에서 string.getBytes()로 바이트열을 얻을 때 지정된 인코딩 (지정하지 않았다면 해당 jvm의 기본 인코딩 - 아마 왠만하면 UTF-8이겠죠?)으로 출력되겠네요
댓글 달기