消息关闭
    暂无新消息!

我是C语言入门菜鸟一只

比如我有一个结构体,里面保存着整型的ID和50个字符长度的名字,但是将记录写入到二进制文件的时候,这些没有被使用的空间也会以00的方式补充进来,也就是我所谓的“空间的浪费”。

我的代码(微长)如下:

#include <stdio.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>

typedef struct NODE{
  int id;
  char name[50];
  struct NODE *next;
}NODE;


NODE *create_node(){
  return calloc(1,sizeof(NODE));
}


void setup_values(NODE *node){
  int id;
  char name[50];
  scanf("%d %s",&id,name);
  node->id = id;
  strcpy(node->name,name);
}

void append(NODE *HEAD){
    NODE *tmp = HEAD;
    while(tmp->next){
        tmp = tmp->next;
    }
    tmp->next = create_node();
    setup_values(tmp->next);
}

void clean_all(NODE *HEAD){
    NODE *target,*t_next;
    target = HEAD->next;
    while(target->next){
        t_next = target->next;
        free(target);
        target = t_next;
    }
    free(target);
    free(HEAD);
}

void write_bin_file(NODE *HEAD, const char *FILE_NAME){
    NODE *tmp = HEAD->next;
    int SPLIT_MARK = 0xFF2277FF;

    FILE *fp = fopen(FILE_NAME,"wb");
    while(tmp){
        fwrite(&tmp->id,sizeof(int),1,fp);
        fwrite(tmp->name,sizeof(tmp->name),1,fp);
        tmp = tmp->next;
        fwrite(&SPLIT_MARK,sizeof(int),1,fp);
    }
    fclose(fp);
}

int main(void)
{
    NODE *head = create_node();

    append(head);
    append(head);

    write_bin_file(head,"d:\\abc.bin");

    clean_all(head);
    return 0;
}

毕竟结构体中name是申请了50个字符,所以没有占用的地方也都被fwrite写进去了。但是如果遇到名字很长比如……

阿里斯基奈何路马里亚蒙娜埃德斯基卢法斯纳贝尔弗兰德歌德尔安纳克洛斯灰粽

那么50个字符的空间就肯定不够用了……

所以,如何修改char name[50]以让它能动态的申请到空间呢?

另外,我在代码中的这句

int SPLIT_MARK = 0xFF2277FF;

是希望能通过FF2277FF来做每组数据的分隔标识……可是如果实现了“动态”写入二进制文件,那么读取的时候又该如何通过fread识别呢?

请详细指教,谢谢!


1个回答

︿ 2

用二进制文件存储不方便。不如改成用文本文件。格式如下:

1
阿里斯
2
基奈何路马里亚蒙

也即奇数行存储id,偶数行存储name。用fscanf/fprintf格式化输入输出很方便,也不用考虑split mark

数据结构上,链表结构体中的name域改成一个字符指针,指向一个字符串池pool的内部。pool中字符串顺序存放,用'\0'分隔。pool可以设置一个初始大小,需要时用realloc进行扩充。

char *pool = calloc(1, POOL_SIZE);
...
pool = realloc(pool, NEW_SIZE);