Программа на C: Как правильно использовать lseek () или fseek () для изменения определенной части файла? - PullRequest
1 голос
/ 18 октября 2010

У меня есть двоичный файл в формате CSV, который содержит несколько записей. Каждая запись вводится как user_name, last_name, first_name, num_wins, num_losses, num_ties. Я создаю метод для обновления определенных игроков записи побед, поражений и связей. Пользователь вводит имя пользователя для изменения, за которым следуют изменения выигрышей, проигрышей и ничьих. Например smithj 4 5 1. Это найдет запись smithj и добавит 4 к победам и т. Д.

Как мне использовать lseek или fseek для этого? Или есть другой способ сделать это?

Ответы [ 3 ]

1 голос
/ 18 октября 2010

Это довольно легко сделать, если каждая запись имеет одинаковое количество байтов.Вы бы проверили первую запись, чтобы увидеть, соответствует ли она, а если нет, то выполните fseek(f, record_size, SEEK_CUR); и проверите следующую запись.

Если каждая запись будет иметь разное количество байтов, все, что я могу подуматьэто то, что вы указали количество байтов, которое находится перед фактической записью.А затем прочитайте это, а затем fseek () столько байтов, чтобы получить следующий размер записи.Я видел, как некоторые бинарные форматы файлов делают это довольно просто.

1 голос
/ 18 октября 2010

Ответ на запрос о записи примера - при условии фиксированного размера записей:

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 до конца один раз для каждой записи, которая должна быть изменена (подумайтеloop).

С записями переменного размера, которые изменяют размер по мере их редактирования, вам придется работать намного усерднее - настолько, что, вероятно, будет проще скопировать старый файл в память по одной записи за раз,измените запись соответствующим образом, а затем запишите измененную запись в новый файл.

1 голос
/ 18 октября 2010

Предполагая, что файл является текстовым файлом, вам придется заполнять линии до постоянной ширины.Затем используйте lseek (), read () и write () для изменения строк.Постоянная длина каждой строки имеет решающее значение: она позволяет вычислить начальную позицию каждой строки.

...