C Чтение двоичных файлов: сколько байтов я должен переместить?

Предположим, у меня есть программа, работающая с бинарными файлами на языке Си.

Предположим, у меня есть 8 объектов (каждый объект представляет собой тип записи структуры) в этом двоичном файле, и я прочитал первые 3 объекта из 8. (Читая 3 объекта из 8, я имею в виду, что я прочитал его и сохранил их в множество)

Я знаю, что для последующего чтения содержимого двоичного файла мне нужно использовать вызов fseek для достижения этой цели. Что меня смущает, так это то, что, предположим, я хочу прочитать 4-й объект из 8, сколько байтов/объектов я должен переместить/пропустить с помощью вызова fseek?

Я должен звонить

fseek(fp, sizeof(struct record) * 3, SEEK_SET);

or

fseek(fp, sizeof(struct record) * 4, SEEK_SET);

person DigitalSoul    schedule 18.03.2019    source источник
comment
Вы экспериментировали? У вас могут быть записи с уникальным содержанием, и вы можете проверить, что получится.   -  person Yunnosch    schedule 18.03.2019
comment
Пожалуйста, объясните это sizeof(struct record, SEEK_SET).   -  person Yunnosch    schedule 18.03.2019
comment
Является ли второе отличие (3 против 4) преднамеренным? Является ли первое различие (выше) преднамеренным? Уточните, пожалуйста, о чем именно вы спрашиваете. Объясните свои аргументы в пользу обеих версий.   -  person Yunnosch    schedule 18.03.2019
comment
Извините, была опечатка, должно быть fseek(fp, sizeof(struct record), SEEK_SET * 3)   -  person DigitalSoul    schedule 18.03.2019
comment
Если подумать логически, чтобы получить первую запись в файле, вы ищете позицию 0. Чтобы получить второе, вы стремитесь к позиции sizeof(struct record). Теперь, как бы вы искали третью запись?   -  person Some programmer dude    schedule 18.03.2019
comment
ну, умножение SEEK_SET на что угодно явно совершенно неправильно, так что другое, вероятно, более верно.   -  person Antti Haapala    schedule 18.03.2019
comment
@Someprogrammerdude Я согласен, но логика первого в 0, второго в 1*N предназначена для людей, которые уже думают C-ish.   -  person Yunnosch    schedule 18.03.2019
comment
Нет 3 против 4 не преднамеренно, просто случайные числа. Я немного поэкспериментировал со своим кодом, но он ведет себя странно, он не пропустил/не переместил столько байтов, сколько я хотел. Я спрашиваю о том, что я хочу намеренно хранить данные в этом двоичном файле в несколько массивов, но, как мы все знаем, перед сохранением этих данных я должен сначала прочитать, но у меня мало опыта работы с двоичным файлом, поэтому чтобы быть конкретным, я сейчас не знаю, сколько байтов я должен предоставить для fseek, чтобы пропустить/перейти к правильному байту для чтения.   -  person DigitalSoul    schedule 18.03.2019
comment
Я думаю, что ваш вопрос прояснится, если вы удалите непреднамеренные различия между тем или иным. (Кстати, голосование не мое.)   -  person Yunnosch    schedule 18.03.2019
comment
Итак, всегда ли первый объект в двоичном файле начинается с 0 байт? А второй объект имеет размер байта (мой тип)? Третий объект имеет размер 2 * sizeof(my byte) byte?   -  person DigitalSoul    schedule 18.03.2019
comment
@DigitalSoul правильно - это так просто. Это ничем не отличается от массива в памяти. Первый элемент массива имеет нулевое смещение. Второй при 1 * sizeof(элемент). Третье значение 2 * sizeof(элемент).   -  person 4386427    schedule 18.03.2019
comment
Вы не должны изменять свой вопрос, чтобы он содержал ответы из комментариев, изменяйте его только для исправления непреднамеренного искажения того, что вы спрашиваете. Посмотрите на это так: теперь вопрос содержит ТОЛЬКО непреднамеренное различие. Вы совсем не об этом спрашиваете...   -  person Yunnosch    schedule 18.03.2019
comment
Подождите, или вы просто спрашиваете о 0,1,2, против 1,2,3,? В таком случае хорошее редактирование, и меня просто смущает история правок.   -  person Yunnosch    schedule 18.03.2019
comment
Позиция первого объекта в файле, очевидно, sizeof(struct record) * 0, позиция второго смещения sizeof(struct record) * 1 и т. д. В чем проблема?   -  person Jabberwocky    schedule 18.03.2019


Ответы (1)


обычно лучше записать эти вещи, чтобы получить представление о том, как работает отображение памяти, поэтому давайте попробуем представить файл (при условии, что каждая структура имеет размер 4 байта):

byte:   |A-0|A-1|A-2|A-3|B-0|B-1|B-2|B-3|C-0|C-1|C-2|C-3|D-0|D-1|D-2|D-3|E....
        ----------------------------------------------------------------------
struct: | struct A      |struct B       |struct C       |struct D       |s...
        ----------------------------------------------------------------------
address:0   1   2   3   4   5   6   7   8   9  10   11  12  13  14  15  16

как вы можете видеть из визуального представления, файл проиндексирован на основе 0, т.е. первая структура расположена по адресу 0 (sizeof(struct record) * 0), вторая расположена по адресу 4 (sizeof(struct record) *1) и так далее...

отсюда можно вывести для n-го элемента offset = ( sizeof(struct record) * ( n - 1) )

надеюсь стало понятнее...

person Omer Dagan    schedule 18.03.2019