简体   繁体   English

从char []字节获取int

[英]Get int from char[] of bytes

I have a file that I read into a char array. 我有一个文件,我读入一个char数组。

The char array now holds a certain number of bytes, now if I know the file stored a 32bit integer in little endian at position say 0x8, how do I retrieve it from the char array? char数组现在拥有一定数量的字节,现在如果我知道文件存储了一个32位整数的小端,位于0x8位置,我如何从char数组中检索它?

FILE * file = fopen("file");
char buffer[size];
fread(buffer,1,size,file);
int = buffer[0x8]; // What should I do here?
// I imagine it involves some strange pointer
// arithmetic but I can't see what I should do,
// casting to int just takes the first byte,
// casting to (int *) doesn't compile

you need to cast it like so: 你需要像这样抛出它:

int foo = *((int *) &buffer[0x8]);

Which will first cast the spot to a int pointer and the dereference it to the int itself. 这将首先将该点转换为int指针并将其解除引用到int本身。

[watch out for byte-ordering across different machine types though; [注意不同机器类型的字节顺序; some do high bytes first some do low] 有些人做高字节先有些做低

And just to make sure the example is well understood, here's some code showing the results: 只是为了确保这个例子很好理解,这里有一些显示结果的代码:

#include <stdio.h>

main() {
    char buffer[14] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13 };
    int foo = *((int *) &buffer[0x8]);
    int bar = (int) buffer[0x8];

    printf("raw: %d\n", buffer[8]);
    printf("foo: %d\n", foo);
    printf("bar: %d\n", bar);
}

And the results from running it: 运行它的结果:

raw: 8
foo: 185207048
bar: 8

The "easy" way, assuming the array contains a byte of the same endianness as your machine, and that there aren't any special alignment requirements, is: 假设数组包含与您的机器具有相同字节序的字节,并且没有任何特殊的对齐要求,那么“简单”的方法是:

int x = *(int *)&buffer[8];

If you do have an endianness difference, you'll need to handle that. 如果你确实有字节序差异,你需要处理它。 If there's an alignment problem (or even potentially an alignment problem), you should extract the bytes one by one: 如果存在对齐问题(甚至可能存在对齐问题),则应逐个提取字节:

int x = buffer[8] + (buffer[9] << 8) + (buffer[10] <<  16) + (buffer[11] << 24);

Or possibly the other direction if the endianness is the other way. 或者可能是另一个方向,如果字节顺序是另一种方式。

Endianess conversion of a 4byte value is done by changing the two words of that value (16bit), so the less efficient but readable way would be (if data is big endian encoded): 通过更改该值的两个字(16位)来完成4字节值的Endianess转换,因此效率较低但可读的方式(如果数据是大端编码):

int val = 0x00000000;
char* ptr = reinterpret_cast<char*>(&val);
*ptr = buffer[0x0a];
ptr++;
*ptr = buffer[0x0b];
ptr++;
*ptr = buffer[0x08];
ptr++;
*ptr = buffer[0x09];
ptr++;

But there are many many other ways to do it like structs, memcpy... depending on what is your goal (performace, readability,...) 但是还有很多其他方法可以像结构,memcpy那样做...取决于你的目标是什么(性能,可读性,......)

Best regards, Alex 最好的问候,Alex

int *list = (int*)buffer;
int n = fread(buffer, 1, size, file);
for (int i=0; i< n/sizeof(int); i++)
  printf("%d\n", list[i]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM