C/C++文件操作————写文件与读文件以及通讯录的改进 (保姆级教学)

简介: C/C++文件操作————写文件与读文件以及通讯录的改进 (保姆级教学)

1.前言

        在前面我们写到过文件的打开与关闭用到了函数主要是fopen函数,参数是文件的文件名和打开方式,文件关闭函数fclose,参数是流,我们还讲到过流,今天我们讲解一些写文件与读文件函数以及对通讯录的改进还有一些文件的其他函数。

2.写文件函数与读文件函数

功能 函数名 适用于
字符输入函数 fgetc 所有输入流
字符输出函数 fputc 所有输出流
文本行输入函数 fgets 所有输入流
文本行输出函数 fputs 所有输出流
格式化输入函数 fscanf 所有输入流
格式化输出函数 fprintf 所有输出流
二进制输入 fread 文件
二进制输出 fwrite 文件

2.1fputc函数

       我们在cplusplus网中 fputc看到它的第一个参数是int  chararcter,这个含义是想要存储的字符信息,第二个参数是流在这里指fopen函数的返回值,fputc函数是将chararcter存入文件中,我们写一个代码将abcdef放到文件中,详细代码如下:

#include<stdio.h>
int main()
{
  FILE* pf = fopen("data.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  int i;
  for (i = 'a'; i <= 'f'; i++)
  {
    fputc(i, pf);
  }
  fclose(pf);
  pf = NULL;
  return 0;
}

我们运行后打开文件data.txt

我们可以看到abcdef已经写到了文件中 先打开文件,再利用循环利用写入字符函数fputc进行信息的存储。

2.2fgetc函数

       我们进入cplusplus网站fgetc我们看到它的参数是流,返回值是int类型,hfgetc函数的作用是读取文件的一个字符,我们写一个代码读取fputc函数存在文件的信息,详细代码如下:

#include<stdio.h>
int main()
{
  FILE* pf = fopen("data.txt", "r");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  int i,ch;
  for (i = 'a'; i <= 'f'; i++)
  {
    ch = fgetc(pf);
    printf("%c", ch);
  }
  fclose(pf);
  pf = NULL;
  return 0;
}

我们运行结果如下:

2.3fputs函数

        我们进入cplusplus网站fputs,函数的第一个参数是const char *str是将str中的内容传到文件中,第二个参数是流 ,返回类型是int,fputs函数的作用是将字符串传到文件中,我们写一个代码将字符串abcdefgh传到文件中,详细代码如下:

#include<stdio.h>
int main()
{
  FILE* pf = fopen("data.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  char arr[] = "abcdefgh";
  fputs(arr,pf);
  fclose(pf);
  pf = NULL;
  return 0;
}

运行后我们打开data.txt文件 可以看到

我们如果再次将arr内容改为ccc运行后打开data.txt文件

我们还可以看到打开文件后光标都在最前面,而且原来的信息也没有了,那我们是不是可以理解为写入文件是将原来的文件的内容覆盖, 然后写入信息。

2.4fgets函数

       我们进入cplusplus网站fgets看到它的第一个参数是char *str是读取文件后存放在程序的变量,第二个参数int num是在文件中读取几个字符+1,第三个参数是流,返回值是char*,例如我们想读取文件中的abcdefg,详细代码如下:

#include<stdio.h>
int main()
{
  FILE* pf = fopen("data.txt", "r");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  char arr[1006] ;
  char* p = arr;
  p = fgets(p, 7, pf);
  printf("%s", arr);
  fclose(pf);
  pf = NULL;
  return 0;
}

我们运行后可以看到

对于为什么是7,原因很简单,fgets函数会在最后将数组的第num个位置转化为’\0‘,我们进入调试可以看到

2.5fprintf函数

       我们进入 cplusplus网站fprintf 查看fprintf函数的参数,看到这个函数你是不是会想到printf函数,我们同样查看printf函数的参数

我们可以看到他们两个只差流这个参数,fprintf函数是格式化输入文件,我们写一个代码来展示一下这个函数的功能,代码如下:

#include<stdio.h>
struct num {
  float s;
  int i;
  char s1[10];
}S;
int main(){
  FILE* pf = fopen("data.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  S = { 1.23f,10,"wo" };
  fprintf(pf, "%f-%d-%s", S.s, S.i, S.s1);
  fclose(pf);
  pf = NULL;
  return 0;
}

我们运行程序后打开data.txt文件,可以看到

同样我们可以理解为将结构体S里面的内容,以  -  -  的形式输出到文件里。

2.6fscanf函数

        我们进入cplusplus网站fscanf查看fscanf函数的参数,看到fscanf函数我们很容易想到scanf函数,我们同样进入cplusplus网站查看scanf函数的参数,

我们可以看到这两个函数的参数只差了一个流, fscanf函数是将文件中有格式的信息储存在程序中定义的变量里,我们利用fprintf函数储存在文件的内容来初始化结构体S,详细代码如下:

#include<stdio.h>
struct num {
  float s;
  int i;
  char s1[10];
}S;
int main(){
  FILE* pf = fopen("data.txt", "r");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  fscanf(pf,"%f-%d-%s", &S.s, &S.i, &S.s1);
  printf("%f %d %s", S.s, S.i, S.s1);
  fclose(pf);
  pf = NULL;
  return 0;
}

我们运行代码,可以看到

2.7sprintf函数与sscanf函数

       sprintf函数是将数据以字符的形式存在s中, sscanf函数是将s的数据以字符的形式存在程序定义的变量中,我们写一个程序,代码如下:

#include<stdio.h>
struct num {
  int i;
  char arr;
  float f;
};
int main()
{
  struct num s = { 10,'c',1.2f};
  char arr[100] = { 0 };
  sprintf(arr, "%d%c%f", s.i, s.arr, s.f);
  struct num tmp = { 0 };
  sscanf(arr, "%d%c%f", &tmp.i, &tmp.arr, &tmp.f);
  printf("%d %c %f", tmp.i, tmp.arr, tmp.f);
  return 0;
}

运行结果如下:

2.8fwrite函数

       我们进入cplusplus网站fwrite的参数第一个参数是const void *ptr是指向的数据的地址,第二个参数size_t size是单个数据所占据的字节,第三个参数size_t count是要写进文件几个数据,第四个参数是流,特别注意这是以二进制的形式储存在文件中 ,我么们写一个代码展示一下函数的功能,代码如下:

#include<stdio.h>
struct num {
  int i;
  char arr[10];
  char brr[10];
};
int main()
{
  FILE* pf = fopen("data.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  struct num s = { 1,"abcd","efg" };
  fwrite(&s, sizeof(struct num), 1, pf);
  fclose(pf);
  pf = NULL;
  return 0;
}

我们运行代码后,打开data.txt文件可以看到:

由于是二进制的形式存储,所以有些信息我们不能识别。

2.9fread函数

        我们进入cplusplus网站看fread的参数一个参数是const void *ptr是要读取文件信息保存到,第二个参数size_t size是单个数据所占据的字节,第三个参数size_t count是要写进文件几个数据,第四个参数是流,我们读取上个函数的内容,代码如下:

#include<stdio.h>
struct num {
  int i;
  char arr[10];
  char brr[10];
};
int main()
{
  FILE* pf = fopen("data.txt", "r ");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  struct num s;
  fread(&s, sizeof(struct num), 1, pf);
  printf("%d\n%s\n%s", s.i, s.arr, s.brr);
  fclose(pf);
  pf = NULL;
  return 0;
}

运行程序后可以看到

3.通讯录的改进

在程序中加入函数

void init(Struct* pc)
{
  assert(pc);
  FILE* pf = fopen("data.txt", "r");
  if (pf == NULL)
  {
    perror("fopen");
    return;
  }
  while (fread(pc->arr + pc->i , sizeof(struct xinxi), 1, pf))
  {   
    pc->i++;
    addnum(pc);
  }
  fclose(pf);
  pf = NULL;
}

以及函数

void save(Struct* pc)
{
  assert(pc);
  FILE* pf = fopen("data.txt", "w");
  if (pf == NULL)
  {
    perror("fclose");
    return;
  }
  int i;
  for (i = 0; i < pc->i; i++)
  {
    fwrite(pc->arr + i, sizeof(struct xinxi), 1, pf);
  }
  fclose(pf);
  pf = NULL;
}

4.文件的随机读写

4.1fseek函数

根据文件指针的位置和偏移量来定位文件指针,第一个参数是流,第二个参数是偏移量v,第三个参数是相对位置,SEEK_SET是对于最初的位置,SEEK_CUR是对现在的位置,SEEK_END是对最后一位的位置。

我们写一个代码,如下:

#include<stdio.h>
int main()
{
  FILE* pf = fopen("data.txt", "r ");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  int ch;
  ch = fgetc(pf);
  printf("%c", ch);//a
  ch = fgetc(pf);
  printf("%c", ch);//b
  ch = fgetc(pf);
  printf("%c", ch);//c
  fseek(pf, -3, SEEK_CUR);
  ch = fgetc(pf);
  printf("%c", ch);//a
  fclose(pf);
  pf = NULL;
  return 0;
}

运行后为

这个函数有一定的局限性,我们必须对文件的内容非常熟悉,否则不容易输出我们想要的值。

4.2ftell函数

这个函数是计算相对于初始位置的偏移量 ,我们可以写一个代码,如下:

#include<stdio.h>
int main()
{
  FILE* pf = fopen("data.txt", "r ");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  fseek(pf, 0, SEEK_END);
  size_t sz = ftell(pf);
  printf("%d", sz);
  fclose(pf);
  pf = NULL;
  return 0;
}

运行结果为

4.3rewind函数

函数的功能是让指针指向初始位置,我们写一个代码,来展示一下它的功能:

#include<stdio.h>
int main()
{
  FILE* pf = fopen("data.txt", "r ");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  fseek(pf, -1, SEEK_END);
  int ch;
  ch = fgetc(pf);
  printf("%c\n", ch);
  rewind(pf);
  ch = fgetc(pf);
  printf("%c\n", ch);
  fclose(pf);
  pf = NULL;
  return 0;
}

运行结果为

文件的内容为

5.总结

       今天主要包括将数据传入文件的函数,以及将文件中的内容传到程序中的函数,还有一些对于文件中的指针以及偏移量的函数fseek函数,ftell函数,rewind函数的讲解,异界对通讯录的改造.今天的内容就结束了。

目录
相关文章
|
4月前
|
存储 分布式数据库 API
技术好文:VisualC++查看文件被哪个进程占用
技术好文:VisualC++查看文件被哪个进程占用
|
13天前
|
C++ 内存技术
[转]Visual C++内嵌swf文件并播放
[转]Visual C++内嵌swf文件并播放
|
16天前
|
C++
【C++案例】一个项目掌握C++基础-通讯录管理系统
这篇文章通过一个通讯录管理系统的C++项目案例,详细介绍了如何使用C++实现添加、显示、删除、查找、修改和清空联系人等功能。
16 3
|
11天前
|
Linux API C++
超级好用的C++实用库之文件目录操作
超级好用的C++实用库之文件目录操作
22 0
|
27天前
|
JavaScript 前端开发 测试技术
一个google Test文件C++语言案例
这篇文章我们来介绍一下真正的C++语言如何用GTest来实现单元测试。
15 0
|
2月前
|
存储 算法 C++
【C++】C++ QT实现Huffman编码器与解码器(源码+课程论文+文件)【独一无二】
【C++】C++ QT实现Huffman编码器与解码器(源码+课程论文+文件)【独一无二】
|
2月前
|
存储 数据挖掘 C语言
【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】
【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】
|
2月前
|
监控 编译器 C++
【代码讲解】【C/C++】获取文件最后修改的时间(系统时间)
【代码讲解】【C/C++】获取文件最后修改的时间(系统时间)
42 0
|
2月前
|
安全 C++ Windows
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
|
2月前
|
C++
C++通过文件指针获取文件大小
C++通过文件指针获取文件大小
27 0