簡體   English   中英

如何將“十六進制”數字的字符 [4] 轉換為整數 [C/Linux]

[英]How to convert to integer a char[4] of "hexadecimal" numbers [C/Linux]

所以我在 Linux 中處理系統調用。 我正在使用“lseek”來瀏覽文件並使用“read”來閱讀。 我還使用 Midnight Commander 查看十六進制文件。 我必須讀取的接下來的 4 個字節是 little-endian ,看起來像這樣:“2A 00 00 00”。 但當然,字節可以是“2A 5F B3 00”之類的東西。 我必須將這些字節轉換為整數。 我該如何處理? 我最初的想法是將它們讀入 4 個字符的向量,然后從那里構建我的整數,但我不知道如何。 有任何想法嗎?

讓我給你舉一個我嘗試過的例子。 我在文件“44 00”中有以下字節。 我必須將其轉換為值 68 (4 + 4*16):

char value[2];
read(fd, value, 2);
int i = (value[0] << 8) | value[1];

變量 i 是 68 的 17480。

更新:Nvm。 我解決了。 我在換班時混合了索引。 它應該是 value[1] << 8 ... | 值[0]

假設您指向緩沖區:

unsigned char *p = &buf[20];

並且您希望將接下來的 4 個字節視為整數並將它們分配給您的整數,然后您可以其轉換:

int i;
i = *(int *)p;

你剛剛說 p 現在是一個指向 int 的指針,你取消引用那個指針並將它分配給 i。

但是,這取決於您平台的字節序。 如果您的平台具有不同的字節順序,您可能首先必須將字節反向復制到一個小緩沖區,然后使用此技術。 例如:

unsigned char ibuf[4];
for (i=3; i>=0; i--) ibuf[i]= *p++;
i = *(int *)ibuf;


編輯

Andrew Henle 和 Bodo 的建議和評論可以給出:

 unsigned char *p = &buf[20]; int i, j; unsigned char *pi= &(unsigned char)i; for (j=3; j>=0; j--) *pi++= *p++; // and the other endian: int i, j; unsigned char *pi= (&(unsigned char)i)+3; for (j=3; j>=0; j--) *pi--= *p++;

一般注意事項

這個問題似乎有幾個部分——至少如何讀取數據,使用什么數據類型來保存中間結果,以及如何執行轉換。 如果您確實假設文件上的表示由一個 32 位整數的字節組成,所有位都有意義,那么我可能不會使用char[]作為中間,而是使用uint32_tint32_t 如果您知道或假設數據的字節序與機器的本機字節序相同,那么你不需要任何其他字節序。

確定本地字節序

如果您需要計算主機的本機字節序,則可以這樣做:

static const uint32_t test = 1;
_Bool host_is_little_endian = *(char *)&test;

這樣做是值得的,因為很可能您根本不需要進行任何轉換。

讀取數據

我會將數據讀入uint32_t (或可能是int32_t ),而不是讀入char數組。 可能我會將它讀入一個uint8_t數組。

uint32_t data;
int num_read = fread(&data, 4, 1, my_file);
if (num_read != 1) { /* ... handle error ... */ }

轉換數據

了解文件表示是否與主機的字節序匹配是值得的,因為如果匹配,您不需要進行任何轉換(也就是說,在這種情況下,此時您已完成)。 但是,如果您確實需要交換字節順序,則可以使用ntohl()htonl()

if (!host_is_little_endian) {
    data = ntohl(data);
}

(這假設小端和大端是您需要關注的唯一主機字節順序。從歷史上看,還有其他的,這就是字節重新排序函數成對出現的原因,但您極不可能看到其他之一。)

有符號整數

如果你需要一個有符號而不是無符號整數,那么你可以這樣做,但使用聯合:

union {
    uint32_t unsigned;
    int32_t signed;
} data;

以上都是用data.unsigned代替plain data ,最后從data.signed讀出有符號的結果。

暫無
暫無

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

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