2014-03-26 67 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; 
    }; 
} 

它可能不是更快,最有可能的需要一些意見,但它總是很好,以顯示你已經學會了你的按位邏輯的好壞;)