gpt4 book ai didi

c - 使用 fwrite/fread 和数据结构的几个问题

转载 作者:太空宇宙 更新时间:2023-11-04 00:33:33 24 4
gpt4 key购买 nike

我第一次使用 fwrite()fread() 将一些数据结构写入磁盘,我有几个关于最佳实践和正确的做事方式。

我正在写入磁盘(以便我稍后可以读回)的是所有插入到图形结构中的用户配置文件。每个图形顶点都是以下类型:

typedef struct sUserProfile {
char name[NAME_SZ];
char address[ADDRESS_SZ];
int socialNumber;
char password[PASSWORD_SZ];

HashTable *mailbox;
short msgCount;
} UserProfile;

这就是我目前将所有配置文件写入磁盘的方式:

void ioWriteNetworkState(SocialNetwork *social) {
Vertex *currPtr = social->usersNetwork->vertices;
UserProfile *user;

FILE *fp = fopen("save/profiles.dat", "w");

if(!fp) {
perror("fopen");
exit(EXIT_FAILURE);
}

fwrite(&(social->usersCount), sizeof(int), 1, fp);

while(currPtr) {
user = (UserProfile*)currPtr->value;

fwrite(&(user->socialNumber), sizeof(int), 1, fp);
fwrite(user->name, sizeof(char)*strlen(user->name), 1, fp);
fwrite(user->address, sizeof(char)*strlen(user->address), 1, fp);
fwrite(user->password, sizeof(char)*strlen(user->password), 1, fp);
fwrite(&(user->msgCount), sizeof(short), 1, fp);

break;

currPtr = currPtr->next;
}

fclose(fp);
}

注意事项:

  • 您看到的第一个 fwrite() 会将总用户数写入图表中,因此我知道我需要读回多少数据。
  • break 用于测试目的。有成千上万的用户,我仍在试验代码。

我的问题:

  • 看完this我决定在每个元素上使用 fwrite() 而不是编写整个结构。我也避免将指针写入邮箱,因为我不需要保存该指针。那么,这是要走的路吗?多个 fwrite() 而不是整个结构的全局一个?那不是更慢吗?
  • 如何回读此内容?我知道我必须使用 fread() 但我不知道字符串的大小,因为我使用 strlen() 来编写它们。我可以在写入字符串之前写入 strlen() 的输出,但是有没有更好的方法而不需要额外写入?

最佳答案

如果您的程序完全需要可移植性,那么您不应该将整数和短整型作为内存块写入磁盘:当您尝试在具有不同字长的计算机上读取它们时(例如, 32 位 -> 64 位)或不同的字节顺序。

对于字符串,您可以先写长度,也可以在末尾包含终止符。

最好的方法通常是使用基于文本的格式。例如,您可以将每条记录写成单独的行,字段之间用制表符或冒号分隔。 (作为奖励,您不再需要在文件开头写入记录数 --- 只需读入记录直到到达文件末尾。)

编辑:但是如果这是给您的类作业,您可能不需要担心可移植性。将字符串中的 '\0' 终止符写入磁盘以分隔它们。读回时不用担心效率,最慢的是磁盘访问。

甚至 fwrite() 输出整个结构,然后 fread() 全部返回。担心那个指针?读入时用安全值覆盖它。不用担心磁盘上的空间浪费(除非您被要求尽量减少磁盘使用)。

如果您确实需要以可移植二进制格式将非负整数写入磁盘,您可以这样做:

  • 第一个字节是后续字节数
  • 第二个字节是 int 中最重要的非零字节
  • ...
  • 最后一个字节是 int 中的最低有效字节

所以:

  • 0编码为00
  • 1编码为01 01
  • 2编码为01 02
  • 255 -> 01 ff
  • 256 -> 02 01 00
  • 65535 -> 02 ff
  • 65536 -> 03 01 00 00
  • 等等

如果您还需要对负数进行编码,则需要在某处为符号保留一些位。

关于c - 使用 fwrite/fread 和数据结构的几个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2637871/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com