写程序必会的C语言文件操作(上)附手绘图详解

简介: 写程序必会的C语言文件操作(上)附手绘图详解

1. 为什么使用文件


在之前我们写过一个通讯录的博客,在通讯录里我们可以随意增删查改人员的信息,可是此时数据的信息是存放到内存中的,一旦程序退出,数据也将不复存在。下次使用通讯录时,就需要重新录入数据。

我们希望输入的数据可以一直存在,除非我们主动选择删除。这就涉及到了数据的持久化问题。

我们一般进行数据持久化的方式有将数据存放到磁盘,存放到数据库等。

而我们可以直接将数据存储文件里,再将文件存到电脑的硬盘上,就可以做到数据的持久化。


2. 什么是文件


磁盘上的文件就是文件。


然而在程序设计中,我们所谈的文件有两种,一种是程序文件,另一种是数据文件(从文件功能的角度来分类的)。


2.1 程序文件


程序文件又包含源程序文件(后缀为.c),目标文件(Windows环境后缀为.obj),可执行程序(Windows环境后缀为.exe)。


2.2 数据文件


程序文件的数据信息需要存放到数据文件中,我们既可以从程序文件往数据文件里写(输出)信息,也可以从数据文件中向程序文件往外读(输入)信息。


咱们之前所处理数据的输入输出都是以终端为对象的,即从终端的键盘读入数据,运行结果到显示器上,数据是存放到内存里面的。


be97030bf0f2cf7ac1c3be8671677c72_f8f88186cc7e4949862ab3686e80b7e0.png


作了图方便大家理解。


其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理 的就是磁盘上文件。


那我们应该怎么把内存中的东西写入文件中呢?


2.3 文件名


一个文件要有一个独有的文件标识,便于用户识别和引用。


文件标识包含文件路径,文件名主干和文件后缀。


例如: f:\class\test.txt


其中 f:\class\是文件路径,test是文件名主干,.txt是文件后缀。


为了方便起见,文件标识常被称为文件名。


3. 文件的打开和关闭


3.1 文件指针


缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。


每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息。


这个文件信息区究竟是什么类型呢?让我们在VS编译器中stdio.h文件中搜寻一番。


fcd6cf6a44fdb0fc946baf8804f7cdb4_dec9f0ef54a343278968ac3e15228d04.png


可以看到,这些信息是保存在一个结构体变量中的。该结构体类型是由系统 声明的,取名FILE。


不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。


我们一般可以通过一个FILE指针来维护FILE结构的变量。


下面我们创建一个FILE*的指针变量。


3.2 文件的打开和关闭实例


我们在试着以只读的方式在桌面上打开一个叫“你快乐吗”的文件。


如果文件不存在,打印错误,并返回一个空指针。


#include<stdio.h>
int main()
{
  FILE *pf=fopen("C:\\Users\\HP\\Desktop\\你快乐吗.txt", "r");
  if (pf == NULL)
  {
  perror("fopen");
  return 1;
  }
  fclose(pf);
  pf == NULL;
  return 0;
}

2b350c7b288a2621dcf4a0b888dbe0f2_54f8d1c9800f46c4986ae77e7305d290.png


如图,提示没有这个文件。


我们这次以只写“w”的方式打开文件。只写方式如果指定文件不存在,建立一个新的文件。


#include<stdio.h>
int main()
{
  FILE *pf=fopen("C:\\Users\\HP\\Desktop\\你快乐吗.txt", "w");
  if (pf == NULL)
  {
  perror("fopen");
  return 1;
  }
  fclose(pf);
  pf == NULL;
  return 0;
}


642ddd5666c2c1b0da163ef0f5ae8a39_5363b0899acb44f292b0431251d0122d.png


程序没有报错。


b1a3fc4247ce0d8808e3fa9d6052bdaf_54a9a8294df3494081dd806cc373c66b.png


回到桌面,我们创建了一个名叫“你快乐吗”的文件,这个文件本来是没有的。


4. 文件的顺序读写


字符输入函数 fgetc


我们使用字符输入函数fgetc向上面的文件里写入26个英文字母。


#include<stdio.h>
int main()
{
  FILE *pf=fopen("C:\\Users\\HP\\Desktop\\你快乐吗.txt", "w");
  if (pf == NULL)
  {
  perror("fopen");
  return 1;
  }
  int i = 0;
  for (i = 0; i < 26; i++)
  {
  fputc('a'+i, pf);
  }
  fclose(pf);
  pf == NULL;
  return 0;
}


643502122efc677a3046375a2d8e3e5b_cd7ea51cf4bf4867897a565c7e159e91.png


上面程序运行完之后,文件里出现26个英文字母。


int fgetc ( FILE * stream );

函数的返回类型是int,即返回一个ASCII值,读取错误返回一个EOF。


我们也可以从文件里读出数据。


改成只读的形式后用fgetc读取之后打印出来,我们可以这样写。


#include<stdio.h>
int main()
{
  FILE *pf=fopen("C:\\Users\\HP\\Desktop\\你快乐吗.txt", "r");
  if (pf == NULL)
  {
  perror("fopen");
  return 1;
  }
  int i = 0;
  int ch = 0;
  for (i = 0; i < 26; i++)
  {
  ch=fgetc(pf);
  printf("%c ", ch);
  }
  fclose(pf);
  pf == NULL;
  return 0;
}


运行结果:


be7a8cb8df80382751643bd254f3b642_70bc29ecfcc643f988f412c2d8057429.png


可以看出,fgetc函数读完一个值后,会让指针向后移一位。


文本行输出函数 fputs


用fputs可以操作字符串内容。


#include<stdio.h>
int main()
{
  FILE *pf=fopen("C:\\Users\\HP\\Desktop\\你快乐吗.txt", "w");
  if (pf == NULL)
  {
  perror("fopen");
  return 1;
  }
  fputs("hello world", pf);
  fclose(pf);
  pf == NULL;
  return 0;
}


34ef37baa3dcdf5aeae92cd4a3163aa1_b80b791bd78e4788bb72eb0bbaf9cafc.png


文本行输入函数 fgets


用fgets读取数据到内存。


char * fgets ( char * str, int num, FILE * stream );

实际上它所读取到的数据比我们所输入的数据少一个,比如我们输入num为5,那么它只能读4个数据。


#include<stdio.h>
int main()
{
  FILE *pf=fopen("C:\\Users\\HP\\Desktop\\你快乐吗.txt", "r");
  if (pf == NULL)
  {
  perror("fopen");
  return 1;
  }
  char arr[20];
  fgets(arr, 5, pf);
  printf("%s", arr);
  fclose(pf);
  pf == NULL;
  return 0;
}


574410dc1e02c09d42e2e1ee9f99a7a6_161af17222584c429315be4bbf2d4e6d.png


如图,只读取了4个字母。


格式化输出函数 fprintf


int fprintf ( FILE * stream, const char * format, ... );

fprintf是将数据写入文件的函数,我们直接看代码。


#include<stdio.h>
struct S
{
  int n;
  float f;
  char arr[20];
};
int main()
{
  struct S s = { 111,5.55f,"chendadachen" };
  FILE *pf=fopen("C:\\Users\\HP\\Desktop\\你快乐吗.txt", "w");
  if (pf == NULL)
  {
  perror("fopen");
  return 1;
  }
  fprintf(pf, "%d %f %s", s.n, s.f, s.arr);
  fclose(pf);
  pf == NULL;
  return 0;
}


运行结果如下,结构体的数据成功输入。


e08e12aa9e363249a43df8c02d9e6482_c03a71afd5d340c4951416c5ca26919c.png


格式化输入函数 fscanf


我们这次将结构体置空,从上面的文件中读取信息然后打印到屏幕上。


#include<stdio.h>
struct S
{
  int n;
  float f;
  char arr[20];
};
int main()
{
  struct S s = { 0 };
  FILE *pf=fopen("C:\\Users\\HP\\Desktop\\你快乐吗.txt", "r");
  if (pf == NULL)
  {
  perror("fopen");
  return 1;
  }
  fscanf(pf, "%d %f %s", &(s.n), &(s.f), s.arr);
  printf("%d %f %s\n", s.n, s.f, s.arr);
  fclose(pf);
  pf == NULL;
  return 0;
}


数据成功读入。


37c97ffa1cc6e956cc81c4f2ccf17e8e_db905f11f1df44148514f37c7d8be88d.png


sprintf


把一个格式化的数据写到字符串中


int sprintf ( char * str, const char * format, ... );
sprintf 可以将一个结构体转换成字符串。
#include<stdio.h>
struct S
{
  int n;
  float f;
  char arr[20];
};
int main()
{
  struct S s = { 111,5.55f,"chendadachen"};
  char a[200] = { 0 };
  sprintf(a, "%d %f %s", s.n, s.f, s.arr);
  printf("%s\n", a);
  return 0;
}


688773273475f881cc12e9d24022ed01_ac7fa3ab6ab74ba5ab6a325fa5891b1e.png


如图,以字符串的形式打印成功。


有没有办法还原回去呢?这就需要下面的sscanf了。


sscanf


将字符串转换成格式化的数据


#include<stdio.h>
struct S
{
  int n;
  float f;
  char arr[20];
};
int main()
{
  struct S s = { 111,5.55f,"chendadachen"};
  char a[200] = { 0 };
  sprintf(a, "%d %f %s", s.n, s.f, s.arr);
  printf("字符串的数据:%s\n", a);
  struct S tmp = { 0 };
  sscanf(a, "%d %f %s", &(tmp.n), &(tmp.f), tmp.arr);
  printf("格式化的数据:%d %f %s", tmp.n, tmp.f, tmp.arr);
  return 0;
}


4e586b83e352d3709b9b15884415ecf5_be4450b1234143868495ddbc003fda00.png


这篇博客旨在总结我自己阶段性的学习,要是能帮助到大家,那可真是三生有幸!如果觉得我写的不错的话还请点个赞和关注哦~我会持续输出编程的知识的!😘😘😘


相关文章
|
1月前
|
存储 自然语言处理 编译器
【C语言】编译与链接:深入理解程序构建过程
【C语言】编译与链接:深入理解程序构建过程
|
3月前
|
编译器 C语言 计算机视觉
C语言实现的图像处理程序
C语言实现的图像处理程序
141 0
|
18天前
|
存储 C语言
【c语言】玩转文件操作
本文介绍了C语言中文件操作的基础知识,包括文件的打开和关闭、文件的顺序读写、文件的随机读写以及文件读取结束的判定。详细讲解了`fopen`、`fclose`、`fseek`、`ftell`、`rewind`等函数的使用方法,并通过示例代码展示了如何进行文件的读写操作。最后,还介绍了如何判断文件读取结束的原因,帮助读者更好地理解和应用文件操作技术。
26 2
|
1月前
|
存储 C语言
C语言文件操作(2)
【10月更文挑战第2天】
|
1月前
|
程序员 编译器 C语言
C语言底层知识------文件操作
本文详细介绍了文件操作的基本概念,包括文件的分类(程序文件和数据文件,其中着重于数据文件的文本文件和二进制文件),流的概念及其在C程序中的应用,以及标准输入输出流stdin、stdout和stderr的作用。作者通过示例展示了如何使用fopen、fclose和常见的读写函数如fgetc、fputc和fgets进行文件操作。
19 2
|
2月前
|
C语言
C语言——文件操作
本文介绍了文件的基本操作,包括文件的打开、关闭、读取和写入。使用`fopen`函数以不同模式(如“r”、“w”等)打开文件,并通过`fclose`关闭。文章详细解释了如何利用`fputc`、`fputs`及`fprintf`进行格式化写入,同时介绍了`fgetc`、`fgets`和`fscanf`用于文件内容的读取。此外,还涵盖了二进制文件的读写方法以及如何通过`fseek`、`ftell`和`rewind`实现文件的随机访问。
49 1
C语言——文件操作
|
1月前
|
存储 缓存 编译器
文件操作——C语言
文件操作——C语言
|
29天前
|
存储 C语言
简述C语言文件操作
简述C语言文件操作
9 0
|
1月前
|
存储 文件存储 C语言
深入C语言:文件操作实现局外影响程序
深入C语言:文件操作实现局外影响程序
|
1月前
|
存储 程序员 编译器
C语言文件操作(1)
【10月更文挑战第1天】