【C文件操作】 /extra-通讯录(文件版实现)

简介: C语言: 文件的读写

C语言: 文件的读写

extra:通讯录文件版实现

文件怎么操作?用什么函数?FILE*是什么?(浅1)

通讯录的进一步

通讯录静态版博客 , 通讯录动态版博客 , 源码

1.为什么使用文件?

因为我们执行代码的时候,结束运行后,数据全部销毁

例如说我们在通讯录使用时,会发现,每次输入的信息没法保留,必须重新输入

所以我们应该使用文件,保存信息,并且读取信息

2.什么是文件?

程序文件 (要运行所需要的文件)

数据文件 (程序数据内容,C语言有“.c”,java有“.java .class”)

例如java “.java”为文本文件 ,“.class”为二进制文件(看不懂无所谓,只要知道两种文件存储数据的方式不同)




3. 文件指针

3.1 FILE*就是文件指针,指向的是一个结构体,包含的一系列信息,但是这些不需要了解,编译器会解决,只要使用这个指针加上对应函数就可以使用文件了。

3.2 文件的打开

FILE * fopen ( const char * filename, const char * mode );

FILE * const char * filename const char * mode

返回值 文件名 打开方式

文件指针(只要有它就可以用文件) 当前路径下的文件(或者完全路径的文件名) 有很多,如下:

 

一般用到四个"w",“r”,“wb”,“rb”

带b的为二进制文件,不带就位文本文件(两种数据存储不同,使用错误会导致结果天翻地覆的不同!)

例如,1 在文本文件中存的是字符 ‘1’,也就是说存的是0x31,但是如果在二进制文件中存的是0x01 ,0x00,0x00,0x00,

它是以数据在内存中存储的形式,将需要保存的所有字节按顺序存储(好处:不用考虑数据类型)(下面实现用到这种,也是因为这个原因)

3.3 文件的关闭

int fclose ( FILE * stream );

这里比较简单输入要关闭的文件的文件指针,失败则返回EOF2

int main()
{
    FILE* pf = fopen("test.txt","wb");//写的时候(wb的话会直接刷新,原来的内容消失),没有这个文件夹自动建立
    if(pf == NULL)
    {
        perror("fopen");
        return 1;
    }
    //.......
    fclose(pf);
    pf = NULL;
}


3.4 文件的使用(这里只将二进制文件)

文件读取size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

size_t void * ptr size_t size size_t count FILE * stream

返回值:正确就匹配后面count,否则小于它 要存放文件过来的内容的起始地址 一个元素对应的字节数 读取元素个数 文件流:文件指针

文件编写size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );


size_t const void * ptr size_t size size_t count FILE * stream

返回值:正确就匹配后面count,否则小于它 要传到文件中的内容的起始地址 一个元素对应的字节数 传入元素个数 文件流:文件指针

补:传入文件时,不是一个一个字节传入,而是遇到‘\n’,就刷一次传过去,或者一些特定函数,如果没有,关闭的时候会把剩余内容传过去。也就是说,如果文件没关闭,可能会有一些信息没传到文件里    

键盘:stdin, 屏幕: stdout

默认打开

4.可保存的通讯录

(用二进制文件是因为我们的结构体有int型,所以在存的时候若要文本文件,我们必然是要格式化存放,这样会导致类型不匹配之类的,这样就会出错!我一开始就是因为这样错了很久🤣)


改动一:由于 屏蔽函数 所以我们需要额外一个文件

void test()
{
  int input = 0;
  struct contact_list total;
  struct contact_list extra;
  init(&total, "Contact1.txt"); //当然可以建立一个doc
  init(&extra, "Contact2.txt");//必须在外面先建立!!!
    do
  {
  menu1();
  printf("请做出选择:>");
  scanf("%d", &input);
  system("cls");
  switch (input)
  {
  case ADD:
    add_man(&total, &extra);
    break;
  case DEL:
    del_man(&total);
    break;
  case SEARCH:
    search_man(&total);
    break;
  case MODIFY:
    modify_man(&total);
    break;
  case SHOW:
    show_all(&total);
    printf("展示成功\n");
    break;
  case SORT:
    sort_all(&total);
    break;
  case EXIT:
            //退出时保存!!!
    keep(&total, "Contact1.txt");
    keep(&extra, "Contact2.txt");
    destroy(&total, &extra);
    printf("退出成功\n");
    break;
  case SECRET:
    secret(&total, &extra);
    break;
  case SHOW_SECRET:
    show_secret(&total, &extra);
    break;
  case REMOVE_SECRET:
    remove_secret(&total, &extra);
    break;
  default:
    printf("输入错误\n");
    break;
  }
  } while (input);
}


增加函数 :keep保存函数

void keep(const struct contact_list* pt, char* str)
{
  FILE* pf = fopen(str, "wb");
  if (NULL == pf)
  {
  perror("保存失败");
  return;
  }
  int i = 0;
  fwrite(&pt->sz, sizeof(int), 1, pf);
  for (i = 0; i < pt->sz; i++)
  {
  fwrite(pt->list + i, sizeof(struct content), 1, pf);
  }
  fclose(pf);
  pf = NULL;
}



改动二:初始化函数,变为从文件内容中提取 (要对第一次录入信息这种情况进行甄别)

void init(struct contact_list* pt, char* str)
{
  assert(pt);
  pt->sz = 0;
  //  memset(pt->list, 0, (MAX + 1) * sizeof(struct content)); 
  FILE* pfr = fopen(str, "rb");
  if (NULL == pfr)
  {
  perror("init");
  return;
  }
  int count = 0;
  fread(&count, sizeof(int), 1, pfr);
  int i = 0;
  struct content* ptr = (struct content*)malloc((count + 1) * sizeof(struct content));
  if (NULL == ptr)
  {
  perror("init");
  return;
  }
  pt->list = ptr;
  pt->capacity = count + 1;
  pt->sz = count;
  for (i = 0; i < count; i++)
  {
  fread(pt->list + i, sizeof(struct content), 1, pfr);
  }
  fclose(pfr);
  pfr = NULL;
}


其他不需要更改,我们这是增加了,保存与提取的动作!要认真分析才能够完成!




文章到此结束!谢谢观看 —>内容参考【比特科技】

可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆!


这是我的代码仓库!(在马拉圈的22.12里)代码仓库


邮箱:2040484356@qq.com


在未来的博客我会完善补充! ↩︎


EOF = -1 ↩︎


目录
相关文章
简易实现通讯录3.0 (实现文件操作)
简易实现通讯录3.0 (实现文件操作)
47 0
|
6月前
|
存储 数据库 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(上)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
51 0
|
6月前
|
存储 编译器 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(下)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
47 0
|
6月前
|
C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(中)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
67 0
|
6月前
文件版本的通讯录
文件版本的通讯录
52 1
|
C语言 Windows
C语言实现通讯录【文件版】——存档联系人信息
C语言实现通讯录【文件版】——存档联系人信息
|
容器
通讯录(文件版)
通讯录(文件版)
132 0
通讯录(文件版)