linux 에서 multibyte, unicode 프로그래밍

wenly의 이미지

제목을 달아놓고 보니 좀 적당하지 않은것 같기도 하지만
일단 "고수" 님들의 조언을 구해봅니다.

win32 로 짜여진 코드를 linux 로 포팅 작업을 하고 있습니다.

이곳저곳의 도움을 많이 받아 어느정도는 해결이 되었는데,
다음과 같은 문제는 영 쉽지가 않네요..

1. snprintf 류 ( snprintf, vsnprintf) 등에선
len = snprintf(NULL, 0, "target = %s, distance = %d.\n", ptar, pdis);
등과 같이 사용하여 snprintf 의 첫번째 매개변수에 사용될 버퍼의
길이(len) 를 미리 확인할수 있는것으로 알고 있습니다.

win32 에서는
char string 에선 _snprintf, _vsnprintf 를,
wchar_t string 에선 _snwprintf, _vsnwprintf 를 이용하여 해당 값을 구할수 있고
linux 에서도
char string 에선 snprintf, vsnprintf 이 동일하게 대응되는 것을 확인했습니다.

그런데 linux 의 wchar_t 에 대응하는 함수를 찾을수가 없네요.
swprintf, vswprintf 등을 확인해봤는데 -1 이 나오는것 같네요.

linux 에서 unicode 로 개발시, 해당 기능에 대해서 경험이 있으신 분의 조언을 구해봅니다.

2. printf 와 wprintf 를 동시에 사용할수 없습니까?
KLDP 에서 검색해보니 char 와 wchar_t 를 동일 스트림에서 사용할수 없다라는 내용을 보았습니다.
그렇다면 모든 linux 어플리케이션은 이러한 제약을 가지고 있나요?
다른 우회(?) 적인 방법이라도.. 없는지요?

이상입니다.

수고하세요~

mithrandir의 이미지

내부에서 utf-8로 다루시는건 어떨까요. 그편이 좀 편할지도 모르겠습니다.

언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net

언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net

obbaya의 이미지

리눅스에서 지원 여부와 상관없이 멀티바이트와 wchar_t는 윈도우 전용이다

라고 생각하는 편이 삶을 윤택하게 해주는 것 같에요;

sizeof wchar_t 을 찍어 보시면 예상과는 다른 결과를 보실 수 도 있고요.

윗 분 말씀처럼 하시는 것이 아름다운 길이라고 생각해요;

wenly의 이미지

개발이 아니라..포팅이기 때문에..
그래서 어떻게든 output 이 나와야 하는..

obbaya 님의 의견은 linux 에서 wchar_t 관련 개발은 포기하는게 정신건강에
이롭다....라는 말씀이신가요?
정말 linux 에서 그정도로 취약한가요?

**
linux 에서 sizeof wchar_t 가 4바이트 인걸 보고 꽤 의아했었습니다. ㅎㅎ

cinsk의 이미지

ISO C 표준에 swprintf()는 버퍼 크기가 부족하면 음수를 리턴하게 되어 있습니다. 정상입니다.

wchar_t의 크기는 compiler마다 다릅니다.

제 경우는, wide character 쪽 함수는 거의 쓰지 않습니다. 무엇보다, wide character는 compiler-specific하기 때문에 unicode와 아무런 상관이 없습니다. 물론, 많은 시스템이 wide character를 unicode에 mapping되게 해 놓았지만, 표준과 상관이 없기 때문에 불안함?을 떨치기 힘듭니다. glibc는 wide character로 32bit UCS-4를 씁니다. 잘 모르지만 Windows에서는 wide character로 16bit UCS-2를 쓰는 것으로 알고 있습니다.

꼭 제 방식이 좋다는 것은 아니지만, (저는 대부분 작업을 linux에서 하는 관계로...) 필요하면 iconv()로 변경해서 작업하고 있습니다. 보통 internationalization 관련해서 완벽한 unicode를 쓰려면 ICU 같은 외부 라이브러리를 쓰는 것이 좋을 겁니다.

http://www.icu-project.org/

간단히.. C 표준은 unicode에 대한 언급이 없습니다. 따라서 wide character와 unicode가 호환된다고 할 수 없습니다. GNU 측에서는 표준을 준수하는 경향을 보이기 때문에, GLIBC의 wide character 관련 함수만 써서 unicode를 다루기에는 무리가 있어 보입니다. Windows는 이에 비해, 표준을 따르지 않고, wide character를 unicode와 밀접하게 붙여서 쓰는 것 같아 보입니다. 따라서 MS의 C 라이브러리를 쓰면 unicode 취급이 쉬워보이나, 표준이 아닌 관계로 다른 OS로 이식하기에 큰 무리가 있어 보입니다.

방법은?? 이식성이 뛰어난, 외부 unicode library를 쓰는게 좋아보이네요.

--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/

klutzy의 이미지

윈도의 wchar_t는 utf-16으로 작동합니다. 윈도 2000 이전 세대에서는 ucs-2만 지원하기는 했고, 또 아직도 ucs-2를 utf-16와 혼동해서 사용하는 경우가(윈도 유니코드는 모두 wchar_t 하나로 표현이 되는 것으로 혼동하는 경우가) 많이 있기는 하지만요.
또한 윈도에서의 wchar_t가 16비트라는 것은 OS 차원에서 정의해둔 것이기 때문에, wchar_t를 윈도 내부에서만 사용하는 것은 큰 문제는 없는 것 같습니다.

comafast의 이미지

1.
vc/c++ 에 (vsnprintf, snwprintf) 쌍이 존재하는 것처럼 유닉스계열도 비슷하게 있습니다.
자세한것을 당연히 매뉴얼을 참고하시면 되겠죠 :-)

참고로, glibc소스의 libio디렉토리를 보시면 tst-wprintf.c tst-swscanf.c 등등이 있으니 참고하시면 될것 같네요.
제가 갖고있는것은 2.7인데 그이후 버젼도 별반 다르지 않을것 같네요.

문제는 제경험상 snwprintf의 리눅스 버젼이 있더라도 wchar_t가 4바이트로 정의되 있어, 기존 소프트웨어와 호환성이 떨어진다는 겁니다. 컴파일시 -fshort-wchar 옵션으로 2바이트로 사용하는 방법도 있지만(http://daftcoder.egloos.com/2557534), 다른옵션으로 컴파일된 라이브러리와는 호환성이 떨어지고 성공사례가 드뭅니다.
대안은 몇가지 있지만 손이 많이 갈겁니다.
A. snwprintf 시리즈 함수들을 2바이트버젼을 따로 직접 작성한다. (라이브러리를 찾아보시면 웬만한것은 있을겁니다.)
B. 인코딩 변환하여 사용한다. (ucs2 <--> ucs4), (any <---> utf8 : 요건 그냥 printf함수 사용하는방법임)
C. 최적화된 라이브러리를 사용한다. (찾으시면 저한테도 연락좀 부탁드립니다. :-) )

2. 요건 모든 OS에 해당되는 내용입니다. EUC-KR과 UTF8을 동시에 출력못합니다. (한쪽이 잘나오면 다른쪽은 깨진다는 말입니다.) CP949와 UCS2를 동시에 출력못합니다. 주로 터미널 설정과 관련있는 부분이지요

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.