C程序:如何正确使用lseek()或fseek()来修改文件的某个部分?

时间:2010-10-18 02:15:34

标签: c seek fseek

我有一个CSV格式的二进制文件,其中包含多个记录。每个记录都以user_name,last_name,first_name,num_wins,num_losses,num_ties的形式输入。我正在创建一种方法来更新某些球员的胜利,失败和关系记录。用户输入要更改的用户名,然后输入胜利,损失和关系的更改。例如,smithj 4 5 1.这将找到smithj记录,并为胜利等添加4

如何使用lseek或fseek来完成此任务?还是有另一种方法可以做到这一点吗?

3 个答案:

答案 0 :(得分:1)

假设文件是​​文本文件,则必须将线条填充到恒定宽度。然后使用lseek(),read()和write()来修改行。每条线的长度恒定是至关重要的:它允许您计算每条线的起始位置。

答案 1 :(得分:1)

如果每个记录的字节数相同,则相当容易。 您将检查第一条记录以查看它是否匹配,如果没有,则执行fseek(f, record_size, SEEK_CUR);并检查下一条记录。

如果每个记录的字节数不同,我能想到的就是你把记录的字节数放在实际记录之前。然后读取,然后fseek()那么多字节来获得下一个记录大小。我已经看到一些二进制文件格式可以做到这一点,这让事情变得相当容易。

答案 2 :(得分:1)

对示例写入请求的响应 - 假设固定大小的记录:

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的声明到结尾的代码。

对于可变大小的记录,在编辑它们时会改变大小,你必须更加努力 - 以至于将旧文件一次复制到内存中一条记录可能更简单,适当地修改记录,以及然后将修改后的记录写入新文件。