short 형 변수 char로 카피

yeilho의 이미지

안녕하세요.

기초적인 질문이겠지만, 통신 프로그램에서 전문을 생성하는데 애매한 부분이 있어서 질문을 올려드립니다.
unsigned short형 변수를 char로 저장하려면 어떻게 해야 되는지 몰라서 질문 올려드립니다.

예를 들어 아래처럼 변수가 선언되어 있다고 하고, unsigned short의 사이즈가 2바이트이면, 이것을 어떻게 new_num에 저장할 수 있나요?

unsigned short num = 60000;
char new_num[2];

저는 memcpy()를 사용하고자 하는데 이렇게 하지 않고 한 바이트씩 저장하는 방법이 있는지 궁금하네요.
다시 말해서 아래처럼 할 수 있는지, 만약 할수 있다면 어떻게 하는지 고수님들의 조언을 구하고자 합니다. 그리고 이외에 다른 방법이 있다면 의견 부탁드릴께요.

new_num[0] = ***;
new_num[1] = ***;

읽어 주셔서 감사합니다.

일호 <><

IDNed의 이미지

엔디안을 따져 주셔야 하네요. :)

무엇인지 모르시면 구글신의 가호를 비시면 엄청나게 나올 겁니다. :D

x86 CPU 계열에서는 리틀엔디안(Little Endian)이니까 다음처럼 하시면 되겠네요..

char는 1byte, short는 2byte로 assume했습니다.

리틀엔디안 표기에 의하면 다음 hex처럼 표현됩니다.
ex)0xabcd -> 0xcd 0xab

따라서 bit shift를 적절히 써주면 되는군요. :D

//대입결과가 큰 경우 어떻게 자르는지는 컴파일러마다 implementation-defined이므로 안전빵 코드를 만들었습니다.

new_num[0]=(char)(num & 0x00ff);
new_num[1]=(char)(num >> 8); //shift 연산 잘리는건 정확히 버린다고 정의

p.s. 수정 : 쉬프트를 1이 아니라 8 해줘야 하는군요...

yeilho의 이미지

답변 주셔서 감사합니다.

네, 클라이언트 서버 모두 사용하는 컴퓨터는 인텔 X86계열이고 OS는 리눅스입니다.

적용을 해보았는데, 에러가 있어서 염치불구하고 질문 올립니다.
사실 어디에서 에러가 나는지 정확히 모르겠지만,

new_num[1]=(char)(num >> 1);

위의 문장에서 '>> 1' 를 하게 되면 1비트만 움직이는건가요?

1바이트가 8비트니까, 혹시 8비트를 움직일 필요는 없나요?

사실은 그렇게 바꿨보았는데도 에러가 있어서 질문을 드립니다.
감사합니다.

Linux rules!!!

yeilho의 이미지

이렇게 저렇게 테스트를 해봤습니다.

new_num[0]=(char)(num & 0xff00) >> 8;
new_num[1]=(char)(num & 0x00ff);

로 바꾸었더니 서버에서 받아주네요.

제가 서버소스를 볼 수 없다보니, 서버에서 어떻게 변환을 하는지 그렇지 않은지 모르는겠네요.

하여튼 오늘 비트와이즈 연산에 대해 조금 배웠습니다.

혹시 더 좋은 답변이나 의견 있으시면 답글 환영할께요.

그리고 의견주신분 감사드립니다.

일호 <><

Linux rules!!!

shockyhan의 이미지

yeilho wrote:
이렇게 저렇게 테스트를 해봤습니다.

new_num[0]=(char)(num & 0xff00) >> 8;
new_num[1]=(char)(num & 0x00ff);

로 바꾸었더니 서버에서 받아주네요.

제가 서버소스를 볼 수 없다보니, 서버에서 어떻게 변환을 하는지 그렇지 않은지 모르는겠네요.

하여튼 오늘 비트와이즈 연산에 대해 조금 배웠습니다.

혹시 더 좋은 답변이나 의견 있으시면 답글 환영할께요.

그리고 의견주신분 감사드립니다.

일호 <><


이기종간의 변환을 다루는 방법으로 htonl()을 활용하는 방법이 있습니다. 받는 쪽에서는 nltoh()하면 되겠지요. short형은 htons()와 nstoh()가 있습니다.
// 보내는 쪽
ushort u = 0x6000;
ushort n = htons(u);
byte c[2]; 

//받는 쪽
byte c[2];
your_recv(c, 2);

ushort *n = (ushort *)c;
ushort u = nstoh(*n);

===========================================================================
Shocky Han
BIM Consultant, Certified Information Systems Auditor
Seoul, Korea.
===========================================================================

only2sea의 이미지

yeilho wrote:
이렇게 저렇게 테스트를 해봤습니다.

new_num[0]=(char)(num & 0xff00) >> 8;
new_num[1]=(char)(num & 0x00ff);

로 바꾸었더니 서버에서 받아주네요.

제가 서버소스를 볼 수 없다보니, 서버에서 어떻게 변환을 하는지 그렇지 않은지 모르는겠네요.

하여튼 오늘 비트와이즈 연산에 대해 조금 배웠습니다.

혹시 더 좋은 답변이나 의견 있으시면 답글 환영할께요.

그리고 의견주신분 감사드립니다.

일호 <><


new_num[0]=(char)(num & 0xff00) >> 8; 
new_num[1]=(char)(num & 0x00ff); 

아쉽게도 해결하셨다고 생각하시는 이 소스는 문제가 있습니다. num[0]의 값이 무조건 0이 될겁니다. 우선순위의 문제로 위의 것은
new_num[0]=((char)(num & 0xff00)) >> 8; 
new_num[1]=(char)(num & 0x00ff); 

과 마찬가지가 됩니다. 따라서 0xff00으로 하고 char로 바꾸면 0이 되어 버리고 왼쪽 shift를 한다고 해도 0이 그대로입니다. 게다가 이것은 Big Endian입니다. 따라서
new_num[0]=(char)((num & 0xff00) >> 8); 
new_num[1]=(char)(num & 0x00ff);

이렇게 하시거나 Little Endian으로 하시려면
new_num[0]=(char)(num & 0x00ff);
new_num[1]=(char)((num & 0xff00) >> 8); 

이렇게 하셔야 제대로 된 결과가 나옵니다

엔디안을 모르는 상태에서 현재 시스템의 엔디안 대로 하시려면... 다음과 같이 하셔도 됩니다.

만일 꼭 카피를 하실 필요가 없으시다면 union을 쓰시면 되겠습니다. 주로 union 써서 이런 것을 처리하는 경우가 가장 많은 것 같습니다.
카피를 해야 한다면...

new_num[0] = *((char*)&num);
new_num[1] = *(((char*)&num)+1);

이렇게 억지로 형변환 해도 되겠구요. 이런것도 엔디안 신경 안 써도 되겠지요. 아니면 반대로

*((unsigned short *)new_num) = num;

이렇게 억지로 밀어 넣으셔도 되구요.

댓글 달기

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