Общие соображения
Кажется, что вопрос состоит из нескольких частей - по крайней мере, как читать данные, какой тип данных использовать для хранения промежуточного результата и как выполнить преобразование. Если вы действительно предполагаете, что представление в файле состоит из байтов 32-разрядного целого числа в порядке с прямым порядком байтов, причем все биты значимы, то, вероятно, я бы не использовал char[]
в качестве промежуточного, а скорее uint32_t
или int32_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
вместо простой data
и в конце зачитайте подписанный результат из data.signed
.