(C++)UTF-16 char배열을 문자열로 바꾸는 팁

train96의 이미지

결론 먼저 : const wchar_t* ad = (const wchar_t*)buff;

C++로 C#이나 Java랑 TCP통신을 하다보면 C#이나 Java에서 Byte배열로 보낸걸 C++에서는 Char로 받아야하는 경우가 종종 있습니다.
(적어도 저의경우 하드웨어적인 제어는 C++, 소프트웨어적인 연산은 C#을 애용하기 때문에 많이 겪는경우죠.)

대표적인 예가
#include
에 있는
recv(ns, buff, 1024, 0);
이런거죠. (buff는 char배열)

여태껏은 문자열로 한글이나 영어만 보내왔기에 euc-kr로 보내면 모든게 해결되서 별로 신경쓰지는 않았지만,
요즘 하는 프로젝트가 일본어나 중국어도 지원해야 하길레 어쩔수 없이 UTF계열로 통신해야하는 문제가 발생했습니다.......

근데 생각보다 이런걸 처리하는 팁이 않보이더군요.

그래서 코드 한줄에 이걸 처리하는 방법을 적어봅니다.

const wchar_t* ad = (const wchar_t*)buff; <-코드 한줄

어때요? 깔끔하죠? ad라는 wchar_t에 문자열이 깔끔하게 담기는걸 발견하실수 있게됩니다!
문제가 있다면 UTF-8이 아닌 UTF-16만 되지만요....
(C#의 string은 UTF-16을쓰니깐 어떤의미 더 좋을수도 있습니다. C#에서 Encoding.Unicode.GetBytes(string) 을 그대로 보내주면 받아낼수 있거든요)

원리는 간단합니다.
wchar_t는 UTF-16을 사용한다.
buff가 가르키는 메모리는 UTF-16에 맞게 byte가 정렬되있다.
wchar_t가 buff가 가르키는 메모리를 wchar_t에 맞게 읽어들이면?
PROFIT!

이방법이 (MultiByteToWideChar보다) 빠르고 안정적인데 별로 알려지지 않은것 같아서 적어봅니다. :)
(wchar_t를 다른 문자열로 바꾸는 방법은 구글에 찾아보면 많이 있습니다.)

문제는 이거 역변환은 잘 안되네요......

Forums: 
kukyakya의 이미지

C++ 표준에서는 wchar_t의 인코딩에 대해 명시하지 않고 있습니다.

구현에 따라 다르므로 wchar_t에는 UTF-16이 아니라 UTF-32로 인코딩되어 저장이 될 수도 있습니다. (int, long과 같은 타입과 마찬가지로 wchar_t의 크기 또한 표준에서는 명시하지 않습니다.)

사용하시는 시스템에서 wchar_t의 인코딩이 UTF-16이고, 해당 시스템에서만 사용할 프로그램이라면 언급하신대로 사용하셔도 큰 문제는 없습니다만 다른 환경으로의 이식성은 포기하셔야 합니다.

익명 사용자의 이미지

그렇군요.
지금 우분투(arm용 gcc제일 최신판)랑 윈도우에서만 실험해봤는데 다른데서는 또 어떻게 될지 모르니 사용하는데 주의가 필요하겠네요.

지적해주셔서 감사합니다 :)

익명 사용자의 이미지

그건 어디까지나 표준 레벨에서의 이야기이고,
de facto standard 적으로는 wchar_t == UTF-16 이 맞습니다.
주류 컴파일러에서 모두 그렇게 처리하는데 그럼 사실상의 표준(de facto standard)이나 다름없는 것입니다.

익명 사용자의 이미지

참고,
https://kldp.org/node/28659
----------
* 개인적으로, 가급적이면 utf-8로 모델링하는게 좋다고 생각합니다. 모든 구현은 플랫폼/프로그래밍언어 무관하게 자체에서는 맘대로, 주고/받을때는 이를(utf-8) 준수하게 하고요.

댓글 달기

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