C语言的文件操作(炒详解)(下)

简介: C语言的文件操作(炒详解)(上)
fgets函数

fgets(字符数组名,n,文件指针)

       该函数的作用是从指定文件中读一个字符串到字符数组中,n表示所得到的字符串中字符的个数(包含字符"\0")

要知道在上边我们在filecom里写进了hello world!

int main()
{
  FILE* fp;
  char str[30];
  if ((fp = fopen("filecom", "r")) == NULL)
  {
    perror("fopen error");
  }
  fgets(str, 11, fp);
  printf("%s", str);
  return 0;
}

💭运行后如图

上面所说包含"\0",在这里我们打印11个字符,然而这里直有10个字符(包含空格),这是因为"\0"也占了一个字符位。


fprintf函数和fscanf函数

       我们对printf函数和scanf应该都已经很熟悉了,下面要讲解的fprint和fscnaf与他们的作用相似,他们最大的区别就是读写的对象不同,fprintf和fscanf函数读写的对象不是终端,而是磁盘文件。

我们在cplusplus官网比较一番

       相比较printf函数,fprintf多了一个参数,fprintf函数形式如下

fprintf(fp,"%d",i);

       作用是将整型变量i的值以"%d"的格式输出到fp指向的文件中

💭举个梨子

int main()
{
  FILE* fp;
  int i = 666;
  if ((fp = fopen("filenum", "w")) == NULL)
  {
    perror("fopen error");
  }
  fprintf(fp, "%d", i);
  return 0;
}

创建一个filenum文件,写入666;

运行结果如下:

如果是%c写入呢,就要参考参照ASCII码表


fscanf函数

格式如下

fscanf(文件类型指针,格式字符串,输入列表);

fscanf(fp , "%d" , &i);

⭐我们先写入abcdefg

💡然后以字符的形式输出

运行后结果正常,输出为参照ASCII对应的数字。


sprintf和sscanf函数

前边已经了解了fprintf和fscanf函数

       💡再对比前边的fprintf函数,相比于fprintf函数将内容写进文件中,可以发现sprintf函数的第一个参数变成了一个字符指针,sprintf的作用即是将格式化的数据转化成字符串,放在传进来的字符数组里。

举一个例子

typedef struct Nums
{
  int a;
  char b;
  double c;
}Nums;
int main()
{
  char str[30] = "0";
  Nums nums = { 3,'f',1.5 };
  sprintf(str, "%d %c %lf\n", nums.a, nums.b, nums.c);
  printf("%s", str);
  return 0;
}

仔细观擦发现和printf函数差不多,作用也很相似。

sscanf同理

💡sscanf从字符串中读取格式化的数据。

typedef struct Nums
{
  int a;
  char b;
  double c;
}Nums;
int main()
{
  char str[30] = "0";
  Nums nums = { 3,'f',1.5 };
  Nums nums1 = { 0 };
  sprintf(str, "%d %c %lf\n", nums.a, nums.b, nums.c);
  //printf("%s", str);
  sscanf(str, "%d %c %lf", &(nums1.a), &(nums1.b), &(nums1.c));
  printf("%d %c %lf", nums.a, nums.b, nums.c);
  return 0;
}

📖读取str内的元素放进nums1中去,此时再打印结构体变量nums1就会发现已经把str内的数据搬进nums1中啦。


二进制的读写函数

⭐前边所介绍的fputc和fgetc函数,每次只能读写文件的一个字符,但我们在编写程序的过程中常常需要对整块数据进行读写,例如,对一个结构体类型的变量值进行读写,下面进行fread和fwrite函数。

因为写进去的是二进制文件,所以当我们用记事本打开时,看到的都是乱码。

代码如下

typedef struct Nums
{
  int a;
  char b;
  double c;
  char str[10];
}Nums;
int main()
{
  Nums nums = { 1,'c',1.5,"heihei"};
  FILE* pf = fopen("data.txt", "wb");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  fwrite(&nums, sizeof(Nums), 1, pf);
  fclose(pf);
  return 0;
}

运行后如下

       👑接下来我们要将它使用fread再读出来,放进一个结构体中,再将其打印出来,将上边的代码改造一下

📜代码如下

typedef struct Nums
{
  int a;
  char b;
  double c;
  char str[10];
}Nums;
int main()
{
  Nums nums = { 0 };
  FILE* pf = fopen("data.txt", "rb");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  fread(&nums, sizeof(Nums), 1, pf);
  printf("%d %c %f %s\n", nums.a, nums.b, nums.c, nums.str);
  fclose(pf);
  return 0;
}

👉运行后代码如下,我们将nums已经置空了,但打印结果已经说明了一切。

文件的定位

⭐学习了前边的函数,我们这时候又要思考了,在对文件进行操作时,一定要从头开始吗?多不方便哇,这时候就需要文件定位函数来实现对文件的随机读取。

fseek函数

fseek(文件类型指针,位移量,起始点);

      这个函数的作用是移动文件内部的位置指针,其中,“文件类型指针”指向被移动的文件;“移动量”表示移动的字节数,要求位移量是long类型数据。“起始点”表示从何处开始计算位移量,规定的起始点有文件首,当前位置,文件末。

表示方法如图

🙉怎么用呢?

fseek(fp,-20,1);

fseek(fp,-20,SEEK_CUR);

       代码表示将位置指针从当前位置向后退20个字节。

🙉看代码

int main()
{
  FILE* file = fopen("data.txt", "w");
  fputs("This is an apple.", file);
  fseek(file, 9, 0);
  fputs(" sam", file);
  fclose(file);
  return 0;
}

⭐运行后如图

      结合运行结果很容易发现,在替换时将空格也替换了,输入的位移量是九,在输入是从第十个位置继续输入,然后puts里的字符串覆盖原字符串。

fseek(fp,5,0);

      💡 此代码的含义是将文件指针指向距离文件首5个字节的位置,也就是指向字符串中的第六个字符。

rewind函数

💭前边讲过了fseek函数,这里介绍的rewind函数也可以起到定位文件指针的作用

int rewind(文件类型指针);

该函数的作用是使位置指针重新返回文件的开头,该函数没有返回值。

举一个例子

int main()
{
  FILE* fp;
  char ch;
  fp = fopen("data.txt", "r");
  ch = fgetc(fp);
  while (ch != EOF)
  {
    putchar(ch);
    ch = fgetc(fp);
  }
  rewind(fp);
  ch = fgetc(fp);
  while (ch != EOF)
  {
    putchar(ch);
    ch = fgetc(fp);
  }
  fclose(fp);
  return 0;
}

运行结果如图所示

有点懵?再来看一个例子

int main()
{
  int n;
  FILE* pfile;
  char buffer[27];
  pfile = fopen("myfile.txt", "w+");
  for (n = 'A'; n <= 'Z'; n++)
  {
    fputc(n, pfile);
  }
  //rewind(pfile);
  fread(buffer, 1, 26, pfile);
  fclose(pfile);
  buffer[26] = '\0';
  puts(buffer);
  return 0;
}

可以看到将rewind注释掉后,运行结果如下,这是因为在使用fputc时将文件指针移动到了最后,再读的话就是从最后的位置开始读,所以输出结果为空。

如果将rewind解注释,再次运行

与上次运行的结果不同,此时将文件指针重新返回文件的开头,该函数没有返回值。

ftell函数

       嘿嘿嘿,如果上边解释rewind大家还有点不懂,可以结合ftell函数来解释哦!

ftell函数一般形式如下

long ftell(文件类型指针)

       该函数的作用是返回文件指针相对于起始位置的偏移量。

⭐利用同样的实例,来看一下是否rewind函数真的把文件指针搞到了最前边。同样也可以摸清ftell函数的作用。

int main()
{
  int n;
  int size = 0;
  FILE* pfile;
  char buffer[27];
  pfile = fopen("myfile.txt", "w+");
  for (n = 'A'; n <= 'Z'; n++)
  {
    fputc(n, pfile);
  }
  size = ftell(pfile);//看一下此时的文件指针的位置
  printf("%d\n", size);
  rewind(pfile);//指针退回到开头位置
  size = ftell(pfile);
  printf("%d\n", size);//再看一次
  fread(buffer, 1, 26, pfile);
  fclose(pfile);
  buffer[26] = '\0';
  puts(buffer);
  return 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天】
|
1月前
|
存储 C语言
C语言的文件操作
C语言的文件操作
19 0
|
1月前
|
存储 移动开发 Unix
C 语言文件操作详解
C 语言文件操作详解