簡體   English   中英

C; 將2個字節轉換為short,反之亦然

[英]c; converting 2 bytes to short and vice versa

我想將2到2的字節數組bytes1 (小端)轉換成短整數數組,反之亦然。 我期望得到最終數組bytes2 ,它等於初始數組bytes1 我有這樣的代碼:

  int i = 0;
  int j = 0;

  char *bytes1;
  char *bytes2;
  short *short_ints;

  bytes1 = (char *) malloc( 2048 );
  bytes2 = (char *) malloc( 2048 );
  short_ints = (short *) malloc( 2048 );

  for ( i=0; i<2048; i+=2)
   {
     short_ints[j] = bytes1[i+1] << 8 | bytes1[i] ;
     j++;
   }

  j = 0;

  for ( i=0; i<2048; i+=2)
     {
        bytes2[i+1] = (short_ints[j] >> 8)  & 0xff;
        bytes2[i] = (short_ints[j]) ;
        j++;
     }
  j = 0;

現在,誰能告訴我,為什么我沒有得到bytes2陣列,完全一樣bytes1 以及如何正確執行此操作?

建議2個功能。 將所有合並和提取都以無符號方式進行,以消除符號位short (可能是char

符號位是OP的代碼最大的問題。 short_ints[j] = bytes1[i+1] << 8 | bytes1[i] ; 如果將bytes1[i]轉換為int則符號可能會擴展。
另外(short_ints[j] >> 8)擴展符號。

// Combine every 2 char (little endian) into 1 short
void charpair_short(short *dest, const char *src, size_t n) {
  const unsigned char *usrc = (const unsigned char *) src;
  unsigned short *udest = (unsigned short *) dest;
  if (n % 2) Handle_OddError();
  n /= 2;
  while (n-- > 0) {
    *udest = *usrc++;
    *udest += *usrc++ * 256u;
    udest++;
  }
}

// Break every short into 2  char (little endian)
void short_charpair(char *dest, const short *src, size_t n) {
  const unsigned short *usrc = (const unsigned short *) src;
  unsigned char *udest = (unsigned char *) dest;
  if (n % 2) Handle_OddError();
  n /= 2;
  while (n-- > 0) {
    *udest++ = (unsigned char) (*usrc);
    *udest++ = (unsigned char) (*usrc / 256u);
    usrc++;
  }
}

int main(void) {
  size_t n = 2048;  // size_t rather than int has advantages for array index

  // Suggest code style: type *var = malloc(sizeof(*var) * N);
  // No casting of return
  // Use sizeof() with target pointer name rather than target type.
  char *bytes1 = malloc(sizeof * bytes1 * n);
  Initialize(bytes, n); //TBD code for OP-best to not work w/uninitialized data

  // short_ints = (short *) malloc( 2048 );
  // This is weak as `sizeof(short)!=2` is possible

  short *short_ints = malloc(sizeof * short_ints * n/2);
  charpair_short(short_ints, bytes1, n);

  char *bytes2 = malloc(sizeof * bytes2 * n);
  short_charpair(bytes2, short_ints, n);

  compare(bytes1, bytes2, n); // TBD code for OP

  // epilogue 
  free(bytes1);
  free(short_ints);
  free(bytes2);
  return 0;
}

避免使用union方法,因為這取決於平台字節序。

這是一個程序,演示您正在遇到與帶符號移位整數值相關的問題。

#include <stdio.h>
#include <stdlib.h>

void testCore(char bytes1[],
              char bytes2[],
              short short_ints[],
              int size)
{
   int i = 0;
   int j = 0;

   for ( i=0; i<size; i+=2)
   {
      short_ints[j] = bytes1[i+1] << 8 | bytes1[i] ;
      j++;
   }

   j = 0;

   for ( i=0; i<size; i+=2)
   {
      bytes2[i+1] = (short_ints[j] >> 8)  & 0xff;
      bytes2[i] = (short_ints[j]) ;
      j++;
   }

   for ( i=0; i<size; ++i)
   {
      if ( bytes1[i] != bytes2[i] )
      {
         printf("%d-th element is not equal\n", i);
      }
   }
}

void test1()
{
   char bytes1[4] = {-10, 0, 0, 0};
   char bytes2[4];
   short short_ints[2];
   testCore(bytes1, bytes2, short_ints, 4);
}

void test2()
{
   char bytes1[4] = {10, 0, 0, 0};
   char bytes2[4];
   short short_ints[2];
   testCore(bytes1, bytes2, short_ints, 4);
}

int main()
{
   printf("Calling test1 ...\n");
   test1();
   printf("Done\n");
   printf("Calling test2 ...\n");
   test2();
   printf("Done\n");
   return 0;
}

程序輸出:

Calling test1 ...
1-th element is not equal
Done
Calling test2 ...
Done

宇大

這是一個適用於我的testCore版本:

void testCore(char bytes1[],
              char bytes2[],
              short short_ints[],
              int size)
{
   int i = 0;
   int j = 0;
   unsigned char c1;
   unsigned char c2;
   unsigned short s;

   for ( i=0; i<size; i+=2)
   {
      c1 = bytes1[i];
      c2 = bytes1[i+1];
      short_ints[j] = (c2 << 8) | c1;
      j++;
   }

   j = 0;

   for ( i=0; i<size; i+=2)
   {
      s = short_ints[j];
      s = s >> 8;
      bytes2[i+1] = s;
      bytes2[i] = short_ints[j] & 0xff;
      j++;
   }

   for ( i=0; i<size; ++i)
   {
      if ( bytes1[i] != bytes2[i] )
      {
         printf("%d-th element is not equal\n", i);
      }
   }
}

經過測試:

char bytes1[4] = {-10, 0, 25, -4};

char bytes1[4] = {10, -2, 25, 4};

好吧,您需要的是UNION:

#include <stdio.h>
#include <string.h>

union MyShort {
    short short_value;
    struct {
        char byte1;
        char byte2;
    };
};

int main(int argc, const char * argv[])
{
    char a[4]="abcd";
    char b[4]="1234";
    short c[5]; c[4]=0;
    union MyShort d;
    for (int i = 0; i<4; i++) {
        d.byte1 = a[i];
        d.byte2 = b[i];
        c[i] = d.short_value;
    }//next i
    printf("%s\n", (char*)c);
    return 0;
}

結果應為a1b2c3d4。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM