Программа на C: Как правильно использовать lseek() или fseek() для изменения определенной части файла?
У меня есть двоичный файл в формате CSV, который содержит несколько записей. Каждая запись вводится как user_name, last_name, first_name, num_wins, num_losses, num_ties. Я создаю метод для обновления определенного игрока записи побед, поражений и связей. Пользователь вводит имя пользователя для изменения, за которым следуют изменения выигрышей, проигрышей и ничьих. Например smithj 4 5 1. Это найдет запись smithj и добавит 4 к победам и т. Д.
Как мне использовать lseek или fseek для достижения этой цели? Или есть другой способ сделать это?
3 ответа
Ответ на запрос на написание примера - при условии фиксированного размера записей:
enum { RECSIZE = 256 };
char buffer[RECSIZE];
FILE *fp = ...; // File to read from and write to
int recnum = 37; // Counting from record 0
long offset = recnum * RECSIZE;
if (fseek(fp, offset, SEEK_SET) != 0)
...error...
if (fread(buffer, sizeof(buffer), 1, fp) != 1)
...error...
...modify buffer...
if (fseek(fp, offset, SEEK_SET) != 0)
...error...
if (fwrite(buffer, sizeof(buffer), 1, fp) != 1)
...error...
Повторите код из декларации recnum
до конца один раз для каждой записи, которая должна быть изменена (цикл мысли).
С записями переменного размера, которые меняют размер по мере их редактирования, вам придется работать намного усерднее - настолько, что, вероятно, будет проще скопировать старый файл в память по одной записи за раз, соответствующим образом изменив запись, а затем записав изменил запись в новый файл.
Это довольно легко сделать, если каждая запись имеет одинаковое количество байтов. Вы бы проверили первую запись, чтобы увидеть, если это совпадение, а если нет, то сделайте fseek(f, record_size, SEEK_CUR);
и проверьте следующую запись.
Если каждая запись будет иметь разное количество байтов, все, о чем я могу думать, это то, что вы указали количество байтов, которое находится перед фактической записью. А затем прочитайте это в, а затем в fseek() столько байтов, чтобы получить следующий размер записи. Я видел, как некоторые двоичные форматы файлов делают это довольно легко.
Предполагая, что файл представляет собой текстовый файл, вам придется заполнять линии до постоянной ширины. Затем используйте lseek(), read() и write() для изменения строк. Постоянная длина каждой строки имеет решающее значение: она позволяет вам вычислить начальную позицию каждой строки.