我有一个包含多条记录的 CSV 格式的二进制文件。每条记录都以 user_name、last_name、first_name、num_wins、num_losses、num_ties 的形式输入。我正在创建一种方法来更新某些玩家的赢、输和平局记录。用户输入要更改的用户名,然后更改胜负和平局。例如 smithj 4 5 1。这将找到 smithj 记录并将 4 添加到胜利等。
如何使用 lseek 或 fseek 来完成此操作?还是有其他方法可以做到这一点?
假设该文件是一个文本文件,那么您必须将这些行填充到一个恒定的宽度。然后使用 lseek()、read() 和 write() 来修改这些行。每条线的长度恒定是至关重要的:它允许您计算每条线的起始位置。
如果每条记录的字节数相同,这很容易做到。您将检查第一条记录以查看它是否匹配,如果不匹配,则执行fseek(f, record_size, SEEK_CUR);
并检查下一条记录。
如果每条记录的字节数不同,我能想到的就是将记录的字节数放在实际记录之前。然后将其读入,然后 fseek() 那么多字节以达到下一个记录大小。我已经看到一些二进制文件格式可以做到这一点,这使事情变得相当容易。
对示例编写请求的响应 - 假设记录大小固定:
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
对必须修改的每条记录重复一次从声明到结尾的代码(想想循环)。
对于可变大小的记录,在您编辑它们时会改变它们的大小,您必须更加努力地工作 - 以至于将旧文件一次复制一条记录到内存中,适当地修改记录,然后编写修改记录到新文件。