2014-03-26 60 views
0

这非常困难。我正在提取位来收集来自无符号字符数组的信息。有一部分我被卡住了。该数组有这四个字节:它包含0x79,0xE8,0x39,0x1A,我需要将它们反转为0x1A,0x39,0xE8,0x79。我reverse_order函数,而不是给我0x59,0x4,0x89,0x10(这是在阵列其他字节为单位):c中的字节反转顺序

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

#define LATITUDE_OFFSET 4 
#define LONGITUDE_OFFSET 5 

void reverse_order(unsigned char *start, unsigned char *end) 
{ 
    int i = 4; 
    do { 
     *start = *end; 
     ++start; 
     --end; 
     --i; 
    } while(i > 0); 
    int j; 
    for(j=0; j<4; j++) 
    { 
     printf("the value: 0x%x\n", start[j]); 
    } 
} 

int main(void) 
{ 
    unsigned char msg[] = { 
     0x28,0x83,0x63,0x20,0x79, 
     0xE8,0x39,0x1A,0x59,0x04, 
     0x89,0x10,0x8D,0x2E,0xF1, 
     0x11,0x6E,0x00,0x10,0x8D, 
     0x51,0x57,0x29,0x0D 
    }; 
    unsigned long long int time_secs; 
    unsigned char *start, *end; 

    int i, j; 

    //remove garbage 
    time_secs = 0; 
    i = 0;  

    while(msg[i] == 0x28) 
    { 
     ++i; 
    } 

    unsigned char resp = ((msg[i] & 0xF) * 16) + 7; 
    unsigned char resp2 = (msg[i] & 0xF); 
    ++i; 

    int unit_id_length = ((msg[i++] & 0xC0) >> 6)+1; 

    int is_latitude_south = (msg[i] & 0x10) >> LATITUDE_OFFSET; 
    int is_longitude_west = (msg[i] & 0x20) >> LONGITUDE_OFFSET; 

    ++i; 
    start = &msg[i]; 
    i+=3; 
    end = &msg[i];  
    reverse_order(start, end); 
} 

回答

1

这里到底是了固定的版本在原有基础上的版本:

void reverse_order(unsigned char *start, unsigned char *end) 
{ 
    int i = 2; 
    int t; 
    do { 
     t = *start; 
     *start = *end; 
     *end = t; 
     ++start; 
     --end; 
     --i; 
    } while(i > 0); 
    int j; 
    start -= 2; 
    for(j=0; j<4; j++) 
    { 
     printf("the value: 0x%x\n", start[j]); 
    } 
} 

这里是一个修订版:

void 
reverse(unsigned char *start, unsigned char *end) 
{ 
    unsigned char t; 

    while (start < end) { 
     t = *start; 
     *start = *end; 
     *end = t; 

     start++; 
     end--; 
    } 
} 
+0

我标记你的答案是正确的,但出于好奇,你认为使用memcpy可以更好地实现这样的效果吗? – JohnMerlino

+0

@JohnMerlino我不认为'memcpy()'在这里很有帮助。 –

0

你可以决定用下面的代码的字节顺序:

#include <stdio.h> 
#include <stdlib.h> 
int main(int argc, char **argv) 
{ 
    union { 
     short s; 
     char c[sizeof(short)]; 
    }un; 
    un.s = 0x0102; 

    if (sizeof(short) == 2) { 
     if (un.c[0] == 1 && un.c[1] == 2) 
      printf("big-endian\n"); 
     else if (un.c[0] == 2 && un.c[1] == 1) 
      printf("little-endian\n"); 
     else 
      printf("unknown\n"); 
    } else{ 
     printf("sizeof(short) = %d\n", sizeof(short)); 
    } 
    exit(0); 
} 
+0

我想要做的是反向指定四个字节,不确定是否正在使用小端或大端。 – JohnMerlino

+0

对不起,我捡错了...... – PersianGulf

0

你的反向码无法正常工作。

使用一个临时变量:

unsigned char t = *start ; 
*start = *end; 
*end = t ; 

你也只能做一半的迭代,所以在你的函数reverse_order情况i()将2

函数的参数到底是因为没有必要你具有的4硬编码长度计算而是在功能

unsigned char* end = star + 3 ; 
1

我发现你的代码存在以下问题:

  1. 您需要交换值为*start*end
  2. 您需要在循环中将i减去2。否则,您将重新交换值。
  3. 当您打印这些值时,您已经增加了start,以便它不会指向函数被调用时的位置。

这就是我想出了:

void reverse_order(unsigned char *start, unsigned char *end) 
{ 
    int i = 4; 
    unsigned char cp; 
    unsigned char* iter = start; 
    int j; 

    do { 
     /* Swap the contents of *iter and *end */ 
     cp = *iter; 
     *iter = *end; 
     *end = cp; 
     ++iter; 
     --end; 
     i -= 2; 
    } while(i > 0); 
    for(j=0; j<4; j++) 
    { 
     printf("the value: 0x%x\n", start[j]); 
    } 
} 
0

有这个漂亮的XOR伎俩,允许交换两个变量不使用临时:

void reverse_order(unsigned char *start, unsigned char *end) 
{ 
    while (end > start) { 
     *start ^= *end; 
     *end ^= *start; 
     *start ^= *end; 
     ++start; 
     --end; 
    }; 
} 

它可能不是更快,最有可能的需要一些意见,但它总是很好,以显示你已经学会了你的按位逻辑的好坏;)