2016-09-13 13 views
0

Так что я пытаюсь записать значение long в качестве исходного двоичного кода в файл с fwrite(), вот тестовым файлом:номер Записи в качестве исходного двоичного кода в файл

#include<stdio.h> 
int main() { 
    FILE* stream; 
    stream = fopen("write", "wb"); 
    long number = 0xfff; 
    fwrite(&number, sizeof(long), 1, stream); 
} 

При открытии письменного файла в текстовый редактор, это выход:

ff0f 0000 0000 0000 

в то время как я ожидал что-то вроде 0000 0000 0000 0fff.

Как правильно записать нужный результат в качестве исходного двоичного кода?

+0

Поиск «сортировки»/«сериализации». Об этом достаточно, чтобы найти здесь и всю остальную часть Интернета. Используйте shifts/masking для сериализации данных, а не только для записи области памяти. – Olaf

+5

[endianness] (https://en.wikipedia.org/wiki/Endianness) ... темная магия – LPs

+1

Вероятно, это больше связано с тем, как шестнадцатеричные дампы отображаются на экране тем, что вы используете для их отображения. –

ответ

2

Нет проблем. Вы видите, что это ff0f 0000 0000 0000 причина эндианта машины! Попробуйте вместо этого использовать fread()!

+0

Да! fread() правильно считывает длинное значение. – Mossmyr

1

как другие отметили в комментариях, это вопрос «судить». Что это, это только проблема, если вы собираетесь запускать свое программное обеспечение в системах с другой контентой.

This very useful resource - это первый результат поиска «c endian» google, по крайней мере для меня. Надеюсь, это поможет вам.


Редактировать: Я буду копать немного больше деталей ниже.

Для определения того, что является конечным элементом машины, в которой вы в данный момент работаете, напишите известное значение (например, 0xAABBCCDD) в память, затем возьмите указатель на это значение и передайте его символу char * или другому 1- байтовый тип данных. Прочитайте одно и то же значение снова, байт за байтом и сравните порядок с тем, что вы написали. Если они одинаковы, вы находитесь на большой машине. Если нет ... Тогда вы можете оказаться на маленькой (более вероятной) или средней (менее вероятной) конечной машине. Вы можете в любом случае создать «своп-карту» для переупорядочения байтов; поэтому я выбрал четыре байта в приведенном выше примере.

Но как изменить эти значения? Простым способом, как указано here, является использование бит-сдвигов с масками. Вы также можете использовать таблицы и менять их значения.

3

Прочитано Endianness, в котором говорится, как байты расположены в слове (или двойном/квадратном слове и т. Д.) В компьютерной системе.

Я предполагаю, что вы закодировали и скомпилировали этот пример в системе X86, которая является little-endian, поэтому наименее значимые бит COME FIRST. Противоположность этому расположению называется big-endian.

Теперь, очевидно, что ваша цель в этом упражнении является маршалом (или рассолом, в зависимости от того, как предпочитает свой жаргон) несколько байт, которые затем будут извлечены, возможно, другой программой.

Если вы разрабатываете программу, которая использует Fread() и и считывает данные таким же образом (с использованием SizeOf (длинная), так что вы не читаете слишком много данных) и в машине с такими же порядком байтами, он будет волшебным образом работать, и число, которое вы ожидаете, вернется. Но, если вы компилируете и запускаете инструмент «читать» на машине с противоположным контентом, считывая один и тот же файл ввода, ваш номер будет искажен.

Если ваша цель состоит в том, чтобы данные Маршаллом, вы должны быть лучше с инструментом, чтобы помочь вам Маршалловых свои байты в пути, который порядок байт-агностик, то есть библиотека, которая позволяет получить данные в правильный заказ. Там есть библиотеки, которые позаботятся об этом для вас.