C语言文件操作详解(上)

简介: C语言文件操作详解

一:文件指针和流

1:文件指针

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

2.每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。

3.这些信息是保存在一个结构体变量中的。该结构体类型是由系统

声明的,取名FILE.

1.不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
2.每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
3.一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
下面我们可以创建一个FILE* 的指针变量:
FILE* pf;//文件指针变量
4.定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。
5.通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。

2:流

流:一个抽象的概念
引入流的原因:
因为计算机可以跟许许多多各种各样的外部设备进行交互,不断地输入与输出信息
所以程序员在写程序的时候就需要针对不同外部设备学习输入与输出的方式
为了简化程序员写代码的难度和过程,引入了流这样的概念
程序员只需要向流中输入数据,从流中读取数据
而无需关心流如何与外部设备之间的信息交互,比如信息如何到文件中去,如何到屏幕上面等等这些问题
这些问题是由C语言和操作系统共同完成的
而C语言程序,只要运行起来,默认就打开3个流
1.标准输入流 stdin FILE*
2.标准输出流 stdout FILE*
3.标准错误流 stderr FILE*

二:文件的打开与关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。

在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。

1.fopen与fclose函数

打开文件
FILE* fopen(const char* filename, const char* mode);
关闭文件
int fclose(FILE* stream);

fopen:

1.
如果文件成功打开,该函数将返回指向 FILE 对象的指针,该对象可用于在将来的操作中标识流。
2.
否则,将返回空指针。
3.
在大多数库实现中,errno 变量在失败时也设置为特定于系统的错误代码。

fclose:

1.
如果流成功关闭,则返回零值。
失败时,将返回 EOF。
2.fclose具有刷新缓冲区的功能
3.在VS2022的<stdio.h>头文件中,EOF是这么被定义的,即宏定义为-1
#define EOF    (-1)

2.文件打开方式

文件使用方式             含义                     如果指定文件不存在
“r”(只读)    为了输入数据,打开一个已经存在的文本文件    出错
“w”(只写)    为了输出数据,打开一个文本文件             建立一个新的文件
“a”(追加)    向文本文件尾添加数据                      建立一个新的文件
“rb”(只读)   为了输入数据,打开一个二进制文件           出错
“wb”(只写)   为了输出数据,打开一个二进制文件           建立一个新的文件
“ab”(追加)   向一个二进制文件尾添加数据                建立一个新的文件
“r + ”(读写) 为了读和写,打开一个文本文件              出错
“w + ”(读写) 为了读和写,建立一个新的文件              建立一个新的文件
“a + ”(读写)  打开一个文件,在文件尾进行读写           建立一个新的文件
“rb + ”(读写) 为了读和写打开一个二进制文件             出错
“wb + ”(读写) 为了读和写,新建一个新的二进制文件       建立一个新的文件
“ab + ”(读写) 打开一个二进制文件,在文件尾进行读和写   建立一个新的文件

3:实例演示

int main()
{
  FILE* pf = fopen("data.txt", "r");
  //打开同级文件路径下的data.txt文件
  if (pf == NULL)//对有无文件进行判断
  {
    perror("fopen");//打印错误信息
    return 1;
  }
  //关文件
  fclose(pf);
  pf = NULL;
  return 0;
}

三:文件的顺序读写

顺序读写:每次读写完一次之后文件指针就会后移

使用者无法指定文件指针的位置

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

一:fgetc与fputc函数

两者被称为字符输入/输出函数.

仅能适用于字符型数据,

不过可以适用于所有输入流(文件,键盘等等),或者是可以适用于所有输出流(文件,屏幕打印等等)

1:fgetc总述

fgetc
int fgetc(FILE * stream);
功能总述:从流中获取一个字符
1.
返回文件指针所读取到的字符(强转为int类型)
2.
然后文件指针向后偏移至下一个要读取的数据处
3.
当文件读取结束后,该函数返回EOF

下面我们看一下实例

2:fgetc使用实例

我们提前就已经创建好了data.txt这个文件了

int main()
{
  FILE* pf = fopen("data.txt", "r");//注意我们在这里要进行读取的操作,所以以"r"的方式打开
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  //读文件
  int ch = 0;
  while ((ch = fgetc(pf)) != EOF)
  {
    printf("%c\n", ch);
  }
  //关文件
  fclose(pf);
  pf = NULL;
  return 0;
}

这是我自己提前录入到data.txt中的信息

这是最后打印出的数据的信息

3:fputc总述

fputc
int fputc(int character, FILE * stream);
功能总述:向流中写入一个数据
1.
把一个字符写入流中然后移动文件指针
2.
成功后,将返回所写字符。
如果发生写入错误,则返回 EOF并设置错误指示器(ferror)。

4:fputc使用实例

一开始,我们的data.txt中依然是存放的abcdefghi,然后我们进行写入操作

注意,写入操作会先清空原有数据,然后再进行写入!!!

int main()
{
  FILE* pf = fopen("data.txt", "w");//写文件用"w"打开方式
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  //写文件
  int i = 0;
  for (i = 0; i < 26; i++)
  {
    fputc('a' + i, pf);//abcdefghijklmnopqrstuvwxyz
    //打印到屏幕上
    //fputc('a' + i, stdout);
    //fputc('a' + i, stderr);
  }
  //关文件
  fclose(pf);
  pf = NULL;
  return 0;
}

二:fgets与fputs函数

两者被称为文本行输入/输出函数.

1.仅适用于字符串类型的数据

2.不过可以适用于所有输入流(文件,键盘等等),或者是可以适用于所有输出流(文件,屏幕打印等等)

3.注意:fputs可以一次写一行数据到流中,但是不会自动换行,如果想要换行,则需要自行添加’\n’换行符

1:fgets总述

fgets
char* fgets(char* str, int num, FILE * stream);
功能总述:从流中获取一行字符串
1.
把从流中读取到的num-1个字符存入str这个字符串中
1.1.读够num-1个后不读了
1.2.读到'\n'后不读了
2.
换行符使 fgets 停止读取,但它被函数视为有效字符,并包含在复制到 str 的字符串中。
返回值
1.成功后,函数返回 str。
2.如果在尝试读取字符时遇到文件末尾,则设置 eof 指示器 (feof)。
3.如果在读取任何字符之前发生这种情况,则返回的指针为空指针(str 的内容保持不变)。

2:fgets使用实例

此时文件已经提前被改回为abcdefghi

int main()
{
  FILE* pf = fopen("data.txt", "r");
  if (NULL == pf)
  {
    perror("fopen");
    return 1;
  }
  //读文件-读一行
  char arr[10] = { 0 };
  fgets(arr, 10, pf);
  printf("%s\n", arr);
  //关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

上述data.txt文件中存放的数据是:abcdefghi

3:fputs总述

int fputs(const char* str, FILE * stream);
1.功能总述:向流当中写入一行字符串
2.
从str中读取数据写到流中
3.
该函数从指定的地址 (str) 开始复制,直到到达终止空字符 ('\0')。
此终止空字符不会复制到流中。

4:fputs使用实例

int main()
{
  FILE* pf = fopen("data.txt", "w");
  if (NULL == pf)
  {
    perror("fopen");
    return 1;
  }
  //写文件,写一行
  //fputs只负责写入那一行数据,不会给你换行,要是想换行,自己加'\n'
  fputs("hello world", pf);
  fputs("hello friend", pf);
  //关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

三:fscanf与fprintf函数

两者被称为格式化输入/输出函数.

1.可以针对于格式化的数据,例如:结构体

2.可以适用于所有输入流(文件,键盘等等),或者是可以适用于所有输出流(文件,屏幕打印等等)

1:fprintf总述

fprintf
int fprintf ( FILE * stream, const char * format, ... );
1.功能总述:将格式化数据写入流
2.将按格式指向流的 C 字符串写入流。如果 format 包含格式占位符(以 % 开头的子序列),则格式后面的其他参数将被格式化并插入到生成的字符串中,替换其各自的占位符。
3.在 format 参数之后,函数至少需要与格式指定的一样多的其他参数。
例如:
struct S s1 = { 100,3.14f };
fprintf(pf, "%d %f\n", s1.a, s1.s);

2:fprintf使用实例

在这里为了演示fprintf与fscanf对于格式化数据的处理,定义了一个结构体S

struct S
{
  int a;
  float s;
};
int main()
{
  FILE* pf = fopen("data.txt", "w");
  if (NULL == pf)
  {
    perror("fopen");
    return 1;
  }
  //写文件
  struct S s1 = { 100,3.14f };
  fprintf(pf, "%d %f\n", s1.a, s1.s);
  struct S s2 = { 100,3.14f };
  fprintf(pf, "%d %f", s2.a, s2.s);
  //关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

fprintf跟fputs相似,也不会自动进行换行,必须自行加上换行符’\n’后才会换行

3:fscanf总述

fscanf
int fscanf ( FILE * stream, const char * format, ... );
1.功能总述:从流中读取格式化数据写入对应的格式型数据类型的变量中
例子:
struct S s = {0};
fscanf(pf, "%d %f", &(s.a), &(s.s));

4:fscanf使用实例

int main()
{
  FILE* pf = fopen("data.txt", "r");
  if (NULL == pf)
  {
    perror("fopen");
    return 1;
  }
  //读文件
  struct S s = {0};
  fscanf(pf, "%d %f", &(s.a), &(s.s));
  printf("%d %f", s.a, s.s);
  //关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

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