C语言-文件操作函数基础+进阶标准输入流输出流

学习的流程

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

文件操作原理

——————————————————————————————————————————— 

为什么使用文件

——————————————————————————————————————————— 

什么是文件


——————————————————————————————————————————— 

二进制文件 和文本文件

二进制编译器的方式打开 二进制文件,二进制文件是我们不能直接看懂的文件

文本文件就是肉眼看得懂的

——————————————————————————————————————————— 

文件流

文件使用流程是,打开 读写 关闭

并且文件的使用是需要依靠媒介的,也就是流

就比如你需要开电视,你不可能是用手把电视打开,你还得跑过去,很麻烦,所以我们发明了遥控器,这个遥控器也就是中间媒介,不需要你大费周章的再去开电视,只需要遥控器一按,就打开了。

下面进行图解举例。

——————————————————————————————————————————— 

文件指针

因为需要流,所以需要文件指针 

在C语言中,文件操作是通过所谓的“流”来进行的,而文件指针就是这种流的抽象表示。FILE结构体是C标准库中定义的一个数据结构,它用于封装关于文件的信息和用于操作文件的数据。

文件指针通常是指向FILE结构体的指针变量,它用于表示一个打开的文件流。通过文件指针,您可以执行诸如读取、写入、定位和关闭文件等操作。

当您使用fopen函数打开一个文件时,它会返回一个FILE*类型的指针,这就是文件指针。然后,您可以使用这个指针来调用其他文件操作函数,如freadfwritefgetsfputsfprintf

FILE结构指针 称为文件指针 

今天我们讲的主要就是用FILE打开文件

在C语言中,`FILE`结构体定义在标准输入输出库`stdio.h`中,它用于表示一个打开的文件流。`FILE`结构体的定义如下:
```c
typedef struct _iobuf {int  _flag;         /* 文件状态标志 */char *_ptr;         /* 当前读/写的指针 */char *_base;        /* 缓冲区的基地址 */char *_end;         /* 缓冲区的结束地址 *//* 以下成员用于缓冲区管理 */void *_lock;        /* 用于文件锁 */struct _io_functions {int (*read) (struct _iobuf *, char *, int);int (*write) (struct _iobuf *, const char *, int);int (*seek) (struct _iobuf *, long int, int);int (*close) (struct _iobuf *);/* 可能还有其他函数指针 */} _functions;/* 以下成员用于系统特定的信息 */void *_data;        /* 用于存放系统特定的数据 */
} FILE;
```
这个结构体包含了多个用于文件操作的成员变量和函数指针。下面是这些成员的简要说明:
- `_flag`:这个整数成员用于存储文件的状态标志,如是否为末尾(`FEof`)、是否出错(`FError`)等。
- `_ptr`:这个指针成员指向当前读/写的文件位置。
- `_base`:这个指针成员指向缓冲区的开始位置,即文件数据的内存缓冲区。
- `_end`:这个指针成员指向缓冲区的结束位置。
- `_lock`:这个指针成员用于文件锁,它可以用于多线程环境中的同步。
- `_functions`:这个结构体成员包含了文件操作的函数指针,分别用于读取(`read`)、写入(`write`)、定位(`seek`)和关闭(`close`)文件。
- `_data`:这个指针成员用于存放系统特定的数据,通常用于实现特定的文件操作。
文件信息区通常指的是`FILE`结构体中用于存储文件信息和控制文件操作的这部分内容。这些信息包括文件的状态、当前的读写位置、缓冲区信息等。通过操作这些成员,可以实现对文件的读写和控制功能。

———————————————————————————————————————————

文件信息区

文件信息区 也就是FILE的类型

所以我们通过pf来维护 文件信息区的写和读

进行操作的时候 一定要通过文件指针变量找到与他关联的文件

———————————————————————————————————————————

文件的打开和关闭

使用

这里是如果有 也就是打开 没有也就是报错

r--只读

w--创建一个新文件(没有)

—————————————————————————————————————————— 

顺序读写函数的介绍

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

读取文件方式 

 可以和fopen打开文件,配合使用

  • "r":只读模式,打开一个已经存在的文本文件。
  • "w":写入模式,打开一个文本文件用于写入。如果文件已经存在,则之前的内容会被删除。
  • "a":追加模式,打开一个文本文件用于写入。如果文件不存在,则会创建一个新文件。
  • "rb":只读模式,打开一个二进制文件。
  • "wb":写入模式,打开一个二进制文件用于写入。
  • "ab":追加模式,打开一个二进制文件用于写入

打开文件需要用流,也就是一个介质, 

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fopen(打开文件)和fclose(关闭文件)

 fopen` 和 `fclose` 是C语言中用于文件操作的两个基本函数。

fopen语法介绍

`fopen` 函数用于打开一个文件,并返回一个指向该文件的指针。如果打开文件失败,`fopen` 会返回 `NULL`。
函数原型:

```c
FILE *fopen(const char *path, const char *mode);
```

参数:
- `path`: 要打开的文件的路径。
- `mode`: 文件的打开模式(例如:`"r"` 读取模式,`"w"` 写入模式,`"a"` 追加模式等)。
返回值:

fopen参数介绍

如果成功,返回一个指向 `FILE` 对象的指针。
如果失败,返回 `NULL`。

—————————————————————————————————————————— 

fclose语法介绍

`fclose` 函数用于关闭由 `fopen` 函数打开的文件。在关闭文件后,相关的文件指针也会被清空,此后不能再使用该指针进行文件操作。
函数原型:

```c
int fclose(FILE *stream);
```

fclose参数介绍

- `stream`: 由 `fopen` 函数返回的文件指针。
返回值:
- 如果成功,返回 `0`。
- 如果出错,返回 `EOF`。

使用示例
下面是一个简单的使用 `fopen` 和 `fclose` 的例子:

```c
#include <stdio.h>
int main() {FILE *filePtr;char *filename = "example.txt";// 打开文件filePtr = fopen(filename, "r"); // 以读取模式打开文件if (filePtr == NULL) {perror("Error opening file");return -1;}// ... 在这里进行文件操作 ...// 关闭文件fclose(filePtr);filePtr=NULL;return 0;
}
```

在这个例子中,首先以读取模式(`"r"`)打开一个名为 `example.txt` 的文件。如果文件打开成功,我们就有了一个指向该文件的 `FILE` 类型的指针,可以用来读取文件内容。操作完成后,使用 `fclose` 函数关闭文件,释放系统资源。
在使用 `fopen` 和 `fclose` 进行文件操作时,应该始终检查 `fopen` 的返回值以确保文件是否成功打开,

1,并在操作完成后使用 `fclose` 关闭文件,以避免资源泄露和数据丢失。

2,在关闭文件之后让他指向空指针,防止因为是野指针而导致出错(因为这里本质还是指针,指针指向的文件关闭后,指向的是一个空的地址,所以此时也就变成了野指针,所以我们需要指向NULL,防止出现问题)

3,这两个函数没有详细介绍就说了一下语法格式的问题

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fputc(写入字符)

语法格式 

fputs(const char *str, FILE *stream):将一个字符串写入文件。

但是这里只能写入一个字符单次

——————————————————————————————————————————  

写进去a b c

——————————————————————————————————————————  

写进去a-z

读文件,这里需要打印的话需要读取文件,然后才能打印

代码,这这里补充说明一下,fputc函数的使用只能一次写一个字符,要么就是循环输入,并不能直接输入字符串

——————————————————————————————————————————  

 代码1写进去a

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
int main()
{FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen:w:");return 1;}fputc('a', pf);fclose(pf);pf = NULL;return 0;
}

我们发现写进去是没有问题的

——————————————————————————————————————————  

代码2写进去字符串

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
int main()
{FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen:w:");return 1;}fputc('a', pf);//我们预计写入afputc('bcd', pf);//我们预计写入bcdfclose(pf);pf = NULL;return 0;
}

这里我们发现,这里不能输入字符串,还是只能输入一个字符

——————————————————————————————————————————  

代码3循环输入A-Z

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
int main()
{FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen:w:");return 1;}//fputc('a', pf);//fputc('bcd', pf);for (int i = 'A'; i < 'Z'; i++){fputc(i, pf);}fclose(pf);pf = NULL;return 0;
}

这里我们发现是可以的,但是一次只能输入一个字符,并且是连续输入的,这里我们可以知道,fputc输入字符是连续输入的

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fgetc(读字符) 

函数的语法格式 

语法格式getc函数是C语言中的标准库函数之一,用于从指定的文件流中逐个字符地读取字符。它的函数原型如下:

int fgetc(FILE *stream)

上面我们描述过函数需要

fopen(打开)+读取+打印

中间可能还有写入等等,但是基本上是步骤是这个步骤

—————————————————————————————————————————— 

函数的返回参数

getc函数正常读取结束返回的是读取到的字符值。返回值是int类型,范围是0到255,或者是EOF(-1),表示读取结束。 

-1 本质是整数 所以返回类型需要是整形

当你使用 fgetc 时,以下规则适用:

  1. 如果成功读取一个字符,fgetc 返回该字符的 ASCII 码值。在 ASCII 表中,控制字符(如换行符 \n、回车符 \r 等)和空格字符也有对应的数值。

  2. 如果读取遇到文件末尾(即文件中再也没有字符可以读取),fgetc 返回 EOF。在 C 标准库中,EOF 定义为 -1

  3. 如果读取失败(例如,文件指针无效或文件无法打开),fgetc 也会返回 EOF

请注意,fgetc 函数只能读取一个字符,而不是字符串。如果你需要读取多个字符,你需要循环调用 fgetc 或者使用其他函数如 fgets,后者可以读取一行文本。

——————————————————————————————————————————  

函数的读取方式

一个字符一个字符的读取

如果需要所有内容一起读取

那么你需要进行循环读取,读取的字符最好存起来,不等于eof 也就是继续循环,等于的时候也就是停止循环,写一个字符读取一个字符 写一堆字符 读取一堆字符。

—————————————————————————————————————————— 

代码1(单个读取)

当你使用 fgetc 时,以下规则适用:如果成功读取一个字符,fgetc 返回该字符的 ASCII 码值。在 ASCII 表中,控制字符(如换行符 \n、回车符 \r 等)和空格字符也有对应的数值。如果读取遇到文件末尾(即文件中再也没有字符可以读取),fgetc 返回 EOF。在 C 标准库中,EOF 定义为 -1。如果读取失败(例如,文件指针无效或文件无法打开),fgetc 也会返回 EOF。请注意,fgetc 函数只能读取一个字符,而不是字符串。如果你需要读取多个字符,你需要循环调用 fgetc 或者使用其他函数如 fgets,后者可以读取一行文本。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
int main()
{//打开文件并且写入FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen:w:");return 1;}//fputc('a', pf);//fputc('bcd', pf);//这里已经输入A-Z的字符for (int i = 'A'; i <= 'Z'; i++){fputc(i, pf);}//int c = 0;//c = fgetc(pf);//printf("%c ", c);这里会发现不能读取成功并且打印出来fclose(pf);pf = NULL;//这里说明一下为什么需要进行二次打开文件,因为上面的是的写入,不是读取,所以需要关闭文件之后再进行读取// 如果你想要可以读取又可以写入,你也可以用a+,我这里主要是进行举例说明。//打开文件FILE* ps = fopen("text.txt", "r");if (ps == NULL){perror("fopen:w:");return 1;}//单个进行读取 这里需要进行一个变量进行接收,因为这个函数的返回值是返回正确的情况下就会返回数值的ASCII码值,//读取不正确的情况就会返回eof 读取到末尾也会返回eof 所以我们需要用一个变量进行接收,你可以是char 也可以是intint ch = 0;ch =fgetc(ps);printf("%c ", ch);//循环一次进行读取 ,这里你可以用while,也可以用whilefclose(ps);pf = NULL;return 0;
}

可以看到只是读取一个字符A 

—————————————————————————————————————————— 

代码2(循环读取)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
int main()
{//打开文件并且写入FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen:w:");return 1;}//fputc('a', pf);//fputc('bcd', pf);//这里已经输入A-Z的字符for (int i = 'A'; i <= 'Z'; i++){fputc(i, pf);}//int c = 0;//c = fgetc(pf);//printf("%c ", c);这里会发现不能读取成功并且打印出来fclose(pf);pf = NULL;//这里说明一下为什么需要进行二次打开文件,因为上面的是的写入,不是读取,所以需要关闭文件之后再进行读取// 如果你想要可以读取又可以写入,你也可以用a+,我这里主要是进行举例说明。//打开文件FILE* ps = fopen("text.txt", "r");if (ps == NULL){perror("fopen:w:");return 1;}//单个进行读取 这里需要进行一个变量进行接收,因为这个函数的返回值是返回正确的情况下就会返回数值的ASCII码值,//读取不正确的情况就会返回eof 读取到末尾也会返回eof 所以我们需要用一个变量进行接收,你可以是char 也可以是intint ch = 0;ch =fgetc(ps);printf("%c \n", ch);//循环一次进行读取 ,这里你可以用while,并且你这里可以发现 之前读取之后A后面进行读取的时候,只是读取A之后的字符//也就是我们只是读取一次int ca = 0;while ((ca = fgetc(ps)) != EOF){printf("%c ", ca);}fclose(ps);pf = NULL;return 0;
}

——————————————————————————————————————————  

代码3(循环读取)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
int main()
{//打开文件并且写入FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen:w:");return 1;}//fputc('a', pf);//fputc('bcd', pf);//这里已经输入A-Z的字符for (int i = 'A'; i <= 'Z'; i++){fputc(i, pf);}//int c = 0;//c = fgetc(pf);//printf("%c ", c);这里会发现不能读取成功并且打印出来fclose(pf);pf = NULL;//这里说明一下为什么需要进行二次打开文件,因为上面的是的写入,不是读取,所以需要关闭文件之后再进行读取// 如果你想要可以读取又可以写入,你也可以用a+,我这里主要是进行举例说明。//打开文件FILE* ps = fopen("text.txt", "r");if (ps == NULL){perror("fopen:w:");return 1;}//单个进行读取 这里需要进行一个变量进行接收,因为这个函数的返回值是返回正确的情况下就会返回数值的ASCII码值,//读取不正确的情况就会返回eof 读取到末尾也会返回eof 所以我们需要用一个变量进行接收,你可以是char 也可以是intint ch = 0;ch =fgetc(ps);printf("%c \n", ch);//循环一次进行读取 ,这里你可以用while,并且你这里可以发现 之前读取之后A后面进行读取的时候,只是读取A之后的字符//也就是我们只是读取一次int ca = 0;//while ((ca = fgetc(ps)) != EOF)//{//	printf("%c ", ca);//}for (ca = fgetc(ps); fgetc(ps) != EOF; ca++){printf("%c ", ca);}fclose(ps);pf = NULL;return 0;
}

这种循环方式也是可以的,但是很显然,这个还需要修改,有点麻烦,没有while循环好用,所以不详细说明了

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fputs(写入文本)

`fputs` 函数的语法

如下所示:

```c
int fputs(const char *str, FILE *stream);
```

这里的参数含义如下:
- `str`:这是一个指向要写入文件的 C 字符串的指针。字符串可以是任何以 null 字符 `'\0'` 结尾的字符序列。
- `stream`:这是一个指向 `FILE` 对象的指针,该对象标识了输出流,即文件或其他 I/O 设备。
函数返回值:
- 如果写入成功,`fputs` 返回 `str` 指针。
- 如果写入失败,`fputs` 返回 `EOF`。
`fputs` 函数会尝试将 `str` 指向的字符串写入到由 `stream` 指针指向的文件流中。写入操作会一直进行,直到遇到字符串末尾的 null 字符,或者在写入过程中发生错误。如果写入成功,`fputs` 函数会更新文件的位置指针。
下面是一个简单的例子,展示如何使用 `fputs` 函数将一个字符串写入到文件中:

```c
#include <stdio.h>
int main() {FILE *file;// 打开文件用于写入,如果文件不存在则创建它file = fopen("example.txt", "w");if (file == NULL) {perror("Error opening file");return 1;}// 使用 fputs 写入字符串fputs("Hello, World!", file);// 关闭文件fclose(file);return 0;
}
```

———————————————————————————————————————————
在这个例子中,`fputs` 函数会写入 "Hello, World!" 到 "example.txt" 文件中。如果文件已经存在,它的内容将被这个字符串覆盖;如果文件不存在,它将被创建。写入完成后,文件将被关闭。 

写到一行上面去

除非两个主动加上换行\n

———————————————————————————————————————————

代码1单个输入

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
//写入字符串
int main()
{FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("foopen:w:");return 1;}fputs("hellow word", pf);fputs("你好世界", pf);fclose(pf);//关闭pf = NULL;//防止成为野指针,置为空指针return 0;
}

这里我们可以发现,我们不仅可以写入字符串,还可以写入文本

—————————————————————————————————————————— 

代码2循环输入

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
//写入字符串
int main()
{//写入文件FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("foopen:w:");return 1;}fputs("hellow word", pf);fputs("你好世界", pf);for (int i = 0; i < 10; i++){fputs("hellow 世界\n", pf);//这里采取换行符,进行换行}fclose(pf);//关闭pf = NULL;return 0;
}

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fgets(读取文本)

语法格式

`fgets` 函数用于从文件读取一行文本。其语法如下:

```c
char *fgets(char *str, int n, FILE *stream);
```

这里的参数含义如下:
- `str`:这是一个指向字符数组的指针,用于存储从文件中读取的一行文本。
- `n`:这是一个整数,表示 `str` 数组的最大长度(以字符为单位)。
- `stream`:这是一个指向 `FILE` 对象的指针,该对象标识了输入流,即文件或其他 I/O 设备。
函数返回值:
- 如果读取成功,`fgets` 返回 `str` 指针。
- 如果读取失败,`fgets` 返回 `NULL`。
`fgets` 函数会从由 `stream` 指针指向的文件流中读取最多 `n-1` 个字符(因为最后一个字符是为了放置字符串结束符 `'\0'` 而保留的),并将它们存储在 `str` 指向的字符数组中。读取操作会一直进行,直到读取到换行符、文件结束符或发生错误。读取到的字符串末尾会自动加上 null 字符 `'\0'`。
下面是一个简单的例子,展示如何使用 `fgets` 函数从文件中读取一行文本:

```c
#include <stdio.h>
int main() {FILE *file;char line[100]; // 创建一个足够大的数组来存储一行文本// 打开文件用于读取file = fopen("example.txt", "r");if (file == NULL) {perror("Error opening file");return 1;}// 使用 fgets 读取一行文本if (fgets(line, sizeof(line), file) != NULL) {printf("Read line: %s\n", line);} else {printf("Failed to read line.\n");}// 关闭文件fclose(file);return 0;
}
```

在这个例子中,`fgets` 函数会读取 "example.txt" 文件中的一行文本,并将其存储在 `line` 数组中。然后,程序会打印出读取到的文本。

如果文件中的文本超过 `line` 数组的大小,那么超出部分将不会被读取,并且 `fgets` 函数仍然会成功返回。如果文件已经到达文件末尾,`fgets` 函数会读取到空字符串并返回 `NULL`。

——————————————————————————————————————————— 

-1 本质是整数 所以返回类型需要是整形

读取方式

一个字符一个字符的读取

所有内容一起读取

循环读取

读取的字符最好存起来

不等于eof 也就是继续循环

等于的时候 也就是停止循环

写一个字符读取一个字符 写一堆字符 读取一堆字符

———————————————————————————————————————————

读取函数的返回参数

fgetc

如果读取正常,返回的是读取到字符的ASCII码值

如果读取的过程中遇到文件末尾,或者发生错误,就返回EOF
fgets
如果读取正常,返回的是存储读取到的字符串的字符数组的地址
 

如果读取的过程中遇到文件末尾,或者发生错误,返回NULL 

———————————————————————————————————————————

代码1不是循环读取文本

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
//写入字符串
int main()
{//写入文件FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("foopen:w:");return 1;}fputs("hellow word", pf);fputs("你好世界", pf);for (int i = 0; i < 10; i++){fputs("hellow 世界\n", pf);}fclose(pf);//关闭pf = NULL;//读取文件//重申一遍,文件只有读取之后才能打印出来FILE* ps = fopen("text.txt", "r");if (ps == NULL){perror("fopen:r:");return 1;}//不是循环读取文件char arr[1000] = { 0 };fgets(arr, 100, ps);printf("%s  ", arr);fclose(ps);//关闭文件ps = NULL;return 0;
}

这里特地我给出100字节,当然的读取不完的,这里说明单次读取只能读取一行

循环读取可以不遇见NULL之前可以读取全部 

———————————————————————————————————————————

代码2循环读取文本

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdio.h>
//写入字符串
int main()
{//写入文件FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("foopen:w:");return 1;}fputs("hellow word", pf);fputs("你好世界", pf);for (int i = 0; i < 10; i++){fputs("hellow 世界\n", pf);}fclose(pf);//关闭pf = NULL;//读取文件//重申一遍,文件只有读取之后才能打印出来FILE* ps = fopen("text.txt", "r");if (ps == NULL){perror("fopen:r:");return 1;}//循环读取//这里循环读取的需要知道的是,只要是循环读取,其实不管是多少字符读取,其实最后都会读取出来//因为你没有遇见,NULL说明你的文本没有读取完毕,如果你是一次直到读取100字符,那么就会一次读取100字符直到读取完毕遇见NULLchar arr[1000] = { 0 };//这里是字符串 或者长的文本,所以接收的时候,需要给一个数组,不能给一个变量     while (fgets(arr, 100, ps) != NULL){printf("%s ", arr);}fclose(ps);//关闭文件ps = NULL;return 0;
}

这里特地我给出100字节,当然的读取不完的,这里说明单次读取只能读取一行

循环读取可以不遇见NULL之前可以读取全部

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fprintf(指定的格式写到文件里面适用于所有的输出流,可以打印在屏幕上面)+fscanf(指定的格式读取出来,适用于所有的输入流

 fprintf(指定的格式写到文件里面)

两个函数是一样的

打开文件

写文件 fprintf以指定的格式写到信息里面

同时这里是文本的形式写进去的 因为我们都读得懂

代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
struct MyStruct
{char name[20];int age;
};
int main()
{struct MyStruct s = { "张三",23 };FILE* ps = fopen("fprintf.txt", "w");//这里我们进行写入一个文件,没有的话会自动创建一个文件if (ps == NULL){perror("fopen:w:");return 1;}fprintf(ps, "%s %d", s.name, s.age);//以指定格式写入文件fclose(ps);//关闭文件ps = NULL;//指针指向空指针return 0;
}

—————————————————————————————————————————— 

fscanf(指定的格式读取出来,适用于所有的输入流

同理这个和scanf是一样的

数组名本身就是地址

fscanf

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
struct MyStruct
{char name[20];int age;
};
int main()
{struct MyStruct s = { "张三",23 };FILE* ps = fopen("fprintf.txt", "w");if (ps == NULL){perror("fopen:w:");return 1;}//这里是把内容写到文件里面fprintf(ps, "%s %d", s.name, s.age);//写入文件fclose(ps);ps = NULL;//只读,因为你剩下的操作是文件读取,所以这里不行w,但是可以是只读,读取文件FILE* pf = fopen("fprintf.txt", "r");if (pf == NULL){perror("fopen:r:");return 1;}//这里是读取内容,不读取是无法直接打印文件内容的fscanf(pf, "%s %d", s.name, &(s.age));//数组首元素就是地址 不需要取地址 ,此时也就是读取成功printf("%s %d\n", s.name, s.age);//表纯输出流打印文件fprintf(stdout, "%s %d\n", s.name, s.age);//指定输出流,打印文件fclose(pf);pf = NULL;return 0;
}

———————————————————————————————————————————

fprintf(可以打印在屏幕上面

适用于所有的输出流,可以打印在屏幕上面

也就是你可以用fprintf写写入里面,用fscanf进行读取,再用fprintf进行打印

当然这里前面的参数是文件,我们指向的是文件,然后才能打印出来

stdout(补充说明)

stdout 是 C 标准库中的一个文件流,代表标准输出。标准输出通常指的是计算机屏幕,但它也可以被重定向到其他地方,比如一个文件。在 C 语言中,stdout 用于打印程序的输出信息,比如 printf 函数和 fprintf 函数输出的内容。

当你调用 printf 或者 fprintf 函数时,如果不指定文件指针参数,这些函数会默认使用 stdout 作为输出目标。例如:

printf("Hello, World!");

这行代码会将在 stdout 上打印 "Hello, World!"。默认情况下,stdout 指向控制台(屏幕),所以你会在屏幕上看到输出。

你还可以将 stdout 重定向到文件。例如,你可以使用系统命令行将输出重定向到文件:

./program > output.txt

这会使得 program 程序的标准输出被重定向到 output.txt 文件,而不会在屏幕上显示任何内容。

在 C 程序中,你也可以显式地将输出写入 stdout:

fprintf(stdout, "This will go to the screen or a file if redirected.\n");

因为这个不是标准输出流,是指定输出流,所以我们可以指定格式。

这里我们发现我们可以用fprintf函数打印出来

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
struct MyStruct
{char name[20];int age;
};
int main()
{struct MyStruct s = { "张三",23 };FILE* ps = fopen("fprintf.txt", "w");if (ps == NULL){perror("fopen:w:");return 1;}//这里是把内容写到文件里面fprintf(ps, "%s %d", s.name, s.age);//写入文件fclose(ps);ps = NULL;//只读,因为你剩下的操作是文件读取,所以这里不行w,但是可以是只读,读取文件FILE* pf = fopen("fprintf.txt", "r");if (pf == NULL){perror("fopen:r:");return 1;}//这里是读取内容,不读取是无法直接打印文件内容的fscanf(pf, "%s %d", s.name, &(s.age));//数组首元素就是地址 不需要取地址 printf("%s %d\n", s.name, s.age);//表纯输出流打印文件fprintf(stdout, "%s %d\n", s.name, s.age);//指定输出流,打印文件fclose(pf);pf = NULL;return 0;
}

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

sprintf(指定格式转化成字符串)+sscanf(字符串转化成指定格式)

sprintf(指定格式转化成字符串)

格式化的数据转化成字符串sprintf

sprintf 是一个在 C 语言中定义的函数,它的作用是将格式化的字符串和参数转换成字符串,并将结果存储在指定的字符数组中。因此,sprintf 可以用来将文件中的文档内容转化成字符串,也可以用来将刚编写的结构体代码转化为字符串。具体使用方式取决于程序的具体需求。 

这里已经转化为字符串

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
struct MyStruct
{char name[20];int age;
};
int main()
{struct MyStruct s = { "张三",23 };FILE* ps = fopen("fprintf.txt", "w");if (ps == NULL){perror("fopen:w:");return 1;}//这里是把内容写到文件里面fprintf(ps, "%s %d", s.name, s.age);//写入文件fclose(ps);ps = NULL;//只读,因为你剩下的操作是文件读取,所以这里不行w,但是可以是只读,读取文件FILE* pf = fopen("fprintf.txt", "r");if (pf == NULL){perror("fopen:r:");return 1;}//这里是读取内容,不读取是无法直接打印文件内容的fscanf(pf, "%s %d", s.name, &(s.age));//数组首元素就是地址 不需要取地址 //转化为字符串的形式char buf[100] = { 0 };//因为是转化成字符串的形式,所以需要用一个数组进行接收sprintf(buf, "%s %d", s.name, s.age);printf("字符串打印:  %s \n", buf);fclose(pf);pf = NULL;return 0;
}

———————————————————————————————————————————

sscanf(字符串转化成指定格式)

sscanf语法说明

这里是 从结构体读取数据

这里是从buf里面读取

所以sscanf也就是前面加上一个需要读取的名称

两次打印的对比,一样的,但是此时已经不是字符串的格式已经是指定的格式了

 代码总结

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
struct MyStruct
{char name[20];int age;
};
int main()
{struct MyStruct s = { "张三",23 };FILE* ps = fopen("fprintf.txt", "w");if (ps == NULL){perror("fopen:w:");return 1;}//这里是把内容写到文件里面fprintf(ps, "%s %d", s.name, s.age);//写入文件fclose(ps);ps = NULL;//只读,因为你剩下的操作是文件读取,所以这里不行w,但是可以是只读,读取文件FILE* pf = fopen("fprintf.txt", "r");if (pf == NULL){perror("fopen:r:");return 1;}//这里是读取内容,不读取是无法直接打印文件内容的fscanf(pf, "%s %d", s.name, &(s.age));//数组首元素就是地址 不需要取地址 //转化为字符串的形式char buf[100] = { 0 };//因为是转化成字符串的形式,所以需要用一个数组进行接收sprintf(buf, "%s %d", s.name, s.age);printf("字符串打印:  %s \n", buf);//字符串转化为带有格式的形式sscanf(buf, "%s %d", s.name, &(s.age));//我们这里还是这个格式, 把数组转化成格式给到结构体里面fprintf(stdout, "按照格式打印:%s %d\n", s.name, s.age);//指定输出流,打印文件fclose(pf);pf = NULL;return 0;
}

 sscanf(buf, "%s %d", s.name, &(s.age));//我们这里还是这个格式, 把数组转化成格式给到结构体里面,buf是字符串,格式化的输入到结构体里面

———————————————————————————————————————————

下面这个是把bit格式化的读取到buf里面 ,简单的说也就是后面放置的是可以接收的一个空的空间、

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

printf(标准输出流)+scanf(标准输入流)+函数的总结

这里说明一下,printf和scanf经常使用,就不详细举例,直接进行说明。

在C语言中,printf、fprintf、sprintf、scanf、sscanf和fscanf是用于输入和输出数据的函数。下面是它们的区别和通常的使用场景:

  1. printf
    • printf函数用于将格式化的数据输出到标准输出(通常是终端或控制台)。
    • 它不会在输出字符串的末尾添加换行符,所以如果需要换行,需要在格式字符串中显式包含\n。
    • 示例:printf("Hello, World!\n"
  1. fprintf
    • fprintf函数用于将格式化的数据输出到任意指定的文件指针(FILE *)。
    • 它可以将数据输出到文件、网络流等。
    • 示例:FILE *fp = fopen("file.txt", "w"); fprintf(fp, "Hello, World!\n"); fclose(fp);
  1. sprintf
    • sprintf函数用于将格式化的数据输出到一个字符数组或字符串。简单的说就是转化成字符串格式
    • 它不会在输出字符串的末尾添加换行符。
    • 示例:char buffer[100]; sprintf(buffer, "Hello, World!\n"); printf("%s", buffer);

  1. scanf
    • scanf函数用于从标准输入(通常是键盘)读取格式化的数据。
    • 它等待用户输入,并根据指定的格式解析输入的数据。
    • 示例:int num; scanf("%d", &num); printf("You entered: %d\n", num);
  1. sscanf
    • sscanf函数用于从字符串中读取格式化的数据。可以把字符串转化为任何你需要的格式
    • 它将字符串中的数据按照指定的格式解析成变量。
    • 示例:char str[] = "1234"; int num; sscanf(str, "%d", &num); printf("You entered: %d\n", num);
    • 可以把字符串转化为任何你需要的格式
  1. fscanf
    • fscanf函数用于从任意指定的文件指针读取格式化的数据。
    • 它可以从文件、网络流等读取数据。
    • 示例:FILE *fp = fopen("file.txt", "r"); int num; fscanf(fp, "%d", &num); fclose(fp); printf("You entered: %d\n", num);

格式化的数据就是带有格式的数据

比如整形 字符 浮点型

看到结构体不方便 需要转化为字符串 那就是 sprintf

需要转化回来 那就用sscanf, fscanf

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fwrite(二进制形式写进去,写wb)

语法格式

在 C 语言中,`fwrite()` 函数用于向文件写入数据。它的语法格式如下:

```c
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
```

参数说明

1. `ptr`:必需。指向要写入数据的指针。(内容)(arr)
2. `size`:必需。每个数据项的大小(以字节为单位)。(大小)(sizeof(arr[0]))
3. `count`:必需。要写入的数据项的数量。(写入的长度)(sz)
4. `stream`:必需。文件指针,指向目标文件。(写入的目标文件)(pf)

返回值:
- 成功时,返回写入的字节数。
- 出错时,返回 `EOF`。
示例代码:

```c
#include <stdio.h>
int main() {FILE *fp;char str[] = "Hello, World!";size_t len = strlen(str);fp = fopen("example.txt", "w"); // 打开文件用于写入if (fp == NULL) {perror("Error opening file");return 1;}size_t written = fwrite(str, sizeof(char), len, fp); // 写入字符串if (written != len) {perror("Error writing to file");}fclose(fp); // 关闭文件return 0;
}
```

在这个示例中,我们打开了一个名为 "example.txt" 的文件,然后尝试将字符串 "Hello, World!" 写入该文件。`fwrite()` 函数返回实际写入的字节数,我们可以将其与要写入的字符串长度进行比较,以检查是否写入成功。如果写入失败,将通过 `perror` 函数打印错误信息。最后,我们关闭文件并返回。

———————————————————————————————————————————

fwrite(地址,一个元素多大,几个元素,写到哪个流里面)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{FILE* pf = fopen("二进制文件的操作", "wb");if (pf == NULL){perror("二进制打开错误:wb:");return 1;}int arr[] = { 1,2,3,4,5,6,7,8,9,0,12,3,123,123,1,23,231,123,123,312,123,213 };int sz = sizeof(arr) / sizeof(arr[0]);fwrite(arr, sizeof(arr[0]), sz, pf);fclose(pf);pf == NULL;return 0;
}

这里我们可以看到我们把二进制的文件写到里面去了 

这个函数只要记着

fwrite(地址,一个元素多大,几个元素,写到哪个文件里面)

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fread(读取二进制文件)

语法格式 

说明 

`fread()` 函数是 C 语言标准库中的一个函数,用于从文件指针指向的文件中读取数据。它定义在 `<stdio.h>` 头文件中。`fread()` 函数用于读取二进制文件,因为它的读取操作不会转换字符,即读取的字节序列与存储在文件中的序列完全一致。
`fread()` 函数的语法格式如下:

```c
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
```

参数说明:

- `void *ptr`: 指向要读取数据的内存块的指针。函数将从文件读取的数据存储到这个指针指向的内存块中。
- `size_t size`: 每个数据项的大小(以字节为单位)。
- `size_t nmemb`: 要读取的数据项的数量。
- `FILE *stream`: 指向 `FILE` 对象的指针,该 `FILE` 对象标识了要读取的文件。
`fread()` 函数返回读取的字节总数,如果读取失败或到达文件末尾,它可能返回 EOF。
示例代码:

```c
#include <stdio.h>
int main() {FILE *fp;int data;int itemsRead;fp = fopen("data.bin", "rb"); // 打开文件用于二进制读取if (fp == NULL) {perror("Error opening file");return -1;}// 分配足够的内存来存储一个整数data = (int)malloc(sizeof(int));itemsRead = fread(data, sizeof(int), 1, fp); // 读取一个整数if (itemsRead == 1) {printf("Read data: %d\n", *data);} else {printf("Failed to read data\n");}fclose(fp);free(data);return 0;
}


在上面的代码中,`fread()` 函数被用来从名为 "data.bin" 的文件中读取一个整数。这段代码假设文件中只有一个整数,并且使用 `malloc()` 分配了足够的内存来存储这个整数。读取完成后,代码打印出读取的整数值。记得在读取文件后关闭文件流,使用 `fclose()` 函数可以做到这一点。同时,使用 `free()` 函数释放用 `malloc()` 分配的内存是很重要的,以避免内存泄漏。 

———————————————————————————————————————————

代码图解 

版本1 

返回值参数是成功读取的元素

就是你让我读取100个 实际文件里面只有5个 那我只能读取5个 并且打印 

循环读取 这个打印出来也是12345

版本2 

这里是i++等于存到arr里面去了,也就是实际你打印出的是arr,也就是不存在最后指针指向的位置跑到后面,导致空间无法释放

while里面取地址取出的是首元素的地址,pf指向的文件放到了arr里面,所以才说,这里++,实际上,++的是arr数组里面的元素,因为arr已经接收了元素。剩下的就是打印

但是这里还是一个问题就是,不管你读取多少元素,最后都会把arr可以放下的所有的元素进行读取。

 代码总结

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{FILE* pf = fopen("二进制文件的操作", "wb");//wb写入二进制文件if (pf == NULL){perror("二进制打开错误:wb:");return 1;}int arr[] = { 1,2,3,4,5,6,7,8,9,0,12,3,123,123,1,23,231,123,123,312,123,213 };int sz = sizeof(arr) / sizeof(arr[0]);fwrite(arr, sizeof(arr[0]), sz, pf);fclose(pf);pf == NULL;int str[1000] = { 0 };FILE* ps = fopen("二进制文件的操作", "rb");//rb读二进制文件if (ps == NULL){perror("二进制打开错误:wb:");return 1;}//也就是//存储的地方,单个大小,读取大小,文件流fread(str, sizeof(int), 400, ps);//以字节为单位 40个字节也就是10个整形for (int i = 0; i < 100; i++){printf("%d ", str[i]);}fclose(ps);ps == NULL;return 0;
}

超出读取范围,那么就会读取0字节,也就是后面的地址 ,但是我们并没有利用,所以才没有出问题,是不建议这样的,这里只是举例。

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

fseek(根据文件偏移位置读取文件)

语法说明 

 `fseek` 函数是 C 语言标准库中的一个函数,用于在文件指针指向的流中设置读/写位置。其语法格式如下:

```c
#include <stdio.h>
int fseek(FILE *stream, long offset, int origin);
```

参数说明如下:

  `FILE *stream`:指向 `FILE` 对象的指针,该 `FILE` 对象标识了要进行操作的流。
- `long offset`:表示要移动的位数。如果 `offset` 是正数,则文件读/写位置向前移动 `offset` 字节;如果是负数,则向后移动。
- `int origin`:表示 `offset` 的起始点,可以是以下三个常量之一:
  - `SEEK_SET`:从文件的开头开始计算 `offset`(默认值)。
  - `SEEK_CUR`:从当前的文件读/写位置开始计算 `offset`。
  - `SEEK_END`:从文件的末尾开始计算 `offset`。

该函数执行成功时返回 `0`,失败时返回 `-1`。如果发生错误,可以通过 `ferror` 函数检查流是否出错。
请注意,`fseek` 函数对二进制文件和文本文件都是有效的。但是在文本文件中,由于需要考虑字符编码和换行符等因素,`fseek` 可能不会按照预期工作,特别是在不同平台之间移植代码时。

———————————————————————————————————————————

首先我们得有一个概念,读取文件需要有一个接收值。

fseek文件的当前位置SEEK_SET

SEEK_END倒着往前偏移

这几个都是找到f

代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("ofpen:r:");return 1;}int ret = 0;fseek(pf, 4, SEEK_SET);//起始位置ret = fgetc(pf);printf("%c ", ret);fseek(pf, 4, SEEK_CUR);//文件指针当前位置ret = fgetc(pf);printf("%c ", ret);fseek(pf, -9, SEEK_END);//文件末尾开始计算,所以这里是负数,从后往前计算ret = fgetc(pf);printf("%c ", ret);fclose(pf);pf == NULL;return 0;
}

这个函数的目的不是进行打印而是找到偏移量,那么此时就可以进行读取到你需要的数值

比如你可以读取从前往后第3个字节那一个字节,那么你就可以使用这个函数,并且使用读取一个字节的函数打印出来。

如果你需要的是,从前往后第三个字节之后的字节,那么你就可以使用这个函数,配套使用读取函数,进行循环读取打印即可。

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

rewind(回到起始位置)

语法格式 

在 C 语言中,`rewind` 函数用于将文件指针定位到文件的开头。它的语法格式如下:

```c
#include <stdio.h>
rewind(FILE *stream);
```

参数

`stream` 是指向 `FILE` 对象的指针,该对象标识了要重置的文件流。调用 `rewind` 函数后,文件流的位置指针将被重置到文件的开头,就像在使用 `fseek(stream, 0, SEEK_SET)` 一样。
下面是一个使用 `rewind` 的例子:

```c
#include <stdio.h>
int main() {FILE *fp;char buffer[100];fp = fopen("example.txt", "r"); // 打开文件if (fp == NULL) {// 处理错误}fread(buffer, sizeof(char), 100, fp); // 读取文件内容rewind(fp); // 将文件指针重置到文件开头fread(buffer, sizeof(char), 100, fp); // 重新读取文件内容fclose(fp); // 关闭文件return 0;
}
```

在这个例子中,`rewind` 函数被用来在读取文件内容后,将文件指针倒回到文件的开头,以便可以再次读取文件的内容。 

———————————————————————————————————————————

此时读取到f

我们可以用rewind回到起始位置

也就是直接输入文件流,就可以直接回到函数所在的起始位置

代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("ofpen:r:");return 1;}int ret = 0;fseek(pf, 4, SEEK_SET);//起始位置ret = fgetc(pf);printf("%c ", ret);fseek(pf, 4, SEEK_CUR);//文件指针当前位置ret = fgetc(pf);printf("%c ", ret);fseek(pf, -9, SEEK_END);//文件末尾开始计算,所以这里是负数,从后往前计算ret = fgetc(pf);printf("%c \n", ret);rewind(pf);//配合使用,返回文件起始位置ret = fgetc(pf);printf("返回起始位置:%c ", ret);fclose(pf);pf == NULL;return 0;
}

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

ftell(获取当前位置)

语法格式

在 C 语言中,`ftell` 函数用于获取当前文件指针的位置,以字节为单位。它的语法格式如下:

```c
#include <stdio.h>
long ftell(FILE *stream);
```

参数

`stream` 是指向 `FILE` 对象的指针,该对象标识了要查询位置的文件流。函数返回当前文件指针的位置,如果出错,则返回 `-1`。
下面是一个使用 `ftell` 的例子:

```c
#include <stdio.h>
int main() {FILE *fp;long position;char buffer[100];fp = fopen("example.txt", "r"); // 打开文件if (fp == NULL) {// 处理错误}fread(buffer, sizeof(char), 100, fp); // 读取文件内容position = ftell(fp); // 获取当前文件指针的位置printf("当前文件指针的位置是:%ld\n", position);fclose(fp); // 关闭文件return 0;
}
```

在这个例子中,`ftell` 函数被用来获取在读取文件内容后,文件指针当前位置的信息。然后,这个位置被打印出来。请注意,`ftell` 的返回值是一个 `long` 类型的值,因此它可以表示非常大的数字,这取决于文件的大小。 

———————————————————————————————————————————

ftell 函数是C语言标准库中的一个函数,用于获取当前文件位置指针的位置。这个位置是一个长整型数,表示从文件开始的字节偏移量。

换句话说,ftell 可以告诉你当前读/写文件的位置在哪里,这对于确定文件中某个特定位置的读/写操作非常有用。

函数原型定义如下:

long ftell(FILE *stream);

其中 stream 是指向 FILE 对象的指针,该 FILE 对象标识了要查询的流。

使用 ftell 函数时,可以进行以下操作:

  1. 确定当前的文件位置。
  2. 在读取或写入文件后,检查位置是否如预期。
  3. 在处理大文件时,可以利用 ftell 来判断是否已经到达文件末尾。

请注意,ftell 返回的值是在调用 fseek 之前或与之关联的文件操作之后的文件位置。如果在 ftell 之后对文件进行任何操作(如读取、写入或定位),则返回的值将不再准确。

在使用 ftell 时,还应当注意平台的差异,因为 ftell 的行为可能会受到操作系统和文件系统的影响。

从前到后用于获取当前文件位置指针的位置。这里是9,这里返回的是文件的偏移量

代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("ofpen:r:");return 1;}int ret = 0;fseek(pf, 4, SEEK_SET);//起始位置ret = fgetc(pf);printf("%c ", ret);fseek(pf, 4, SEEK_CUR);//文件指针当前位置ret = fgetc(pf);printf("%c ", ret);fseek(pf, -9, SEEK_END);//文件末尾开始计算,所以这里是负数,从后往前计算ret = fgetc(pf);printf("%c \n", ret);rewind(pf);//配合使用,返回文件起始位置ret = fgetc(pf);printf("返回起始位置:%c \n", ret);int s = 0;//这里需要进行一个返回值进行接收s=ftell(pf);//这里我们已经知道返回了初始位置printf("当前位置:%d \n", s);//所以当前位置是1//此时神奇的来了,上面我们已经返回文件初始位置了,我们可以根据偏移量读取位置//因为是从前往后计算当前位置的,同时利用fseek函数把数值移动到最后一位,并且不进行偏移fseek(pf, 0, SEEK_END);//文件末尾开始计算,不进行偏移int a = 0;a = ftell(pf);printf("文件总长度:%d \n", a);fclose(pf);pf == NULL;return 0;
}

可以计算文件总的长度

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

feof(文件读取结束的判定) 

语法格式 

`feof` 函数用于在文件读取操作中判断是否到达文件末尾。如果到达文件末尾,则返回非零值;否则返回零。
语法格式如下:

```c
#include <stdio.h>
int feof(FILE *stream);
```

参数

`stream` 是指向 `FILE` 对象的指针,该 `FILE` 对象标识了要检查的流。通常,这个参数是通过 `fopen` 函数返回的。
函数返回值:
- 如果已到达流 `stream` 的文件末尾,则返回非零值。
- 如果 `stream` 未打开或不是一个有效文件流,则行为未定义。
- 如果没有到达文件末尾,则返回零。

在使用 `feof` 函数时,通常与读取操作配合使用,例如 `fread` 或 `fgets`,以检查是否在读取过程中到达文件末尾。 

简单的说 是来根据返回值来进行判断的

fgetc 在读取到文件末尾时会返回 EOF,这可以通过比较 ch 和 EOF 来判断是否到达文件末尾。在大多数实现中,EOF 是一个非零值

———————————————————————————————————————————

feof文件读取结束的判定

这个不是判断文件是不是结束 是已经结束判断的原因是什么

是结束了 ?还是出错了?

如果是 正常读取结束那么就会进行判定,走if

如果不是正常读取结束,那么此时就会走else

从而打印出错误信息

不要用错了

也就是判断返回值是不是空指针

———————————————————————————————————————————

总结

文本文件

非零 就是正常的

———————————————————————————————————————————

错误的文件描述

也就是返回eof是非零值,也就是符合条件为真

否则为假,不满足条件,打印错误信息

———————————————————————————————————————————

做题 

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

文件缓冲区 

设置缓冲区的目的就是提高效率

举例子来说的话 就是问老师问题,全班70人 ,每个人都要问,一会一个一会一个,那老师说了,你这样存五个问题再来。大家都可以问问题了。


这个代码可以感受到缓冲区的存在

刷新的意义是把缓冲区的文件放到内存里面去

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 

文件操作函数的综合使用 (例题)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{//创建打开文件 只读//写进去FILE* ss = fopen("data.txt", "w");if (ss == NULL){perror("fopen:w:"); return 1;}fputs("hellow JJS", ss);fclose(ss);ss = NULL;//创建打开文件 只读FILE* ps = fopen("data.txt", "r");if (ps == NULL){perror("fopen:w:");return 1;}//打开文件 创建文件 FILE* pf = fopen("data_copy.txt", "w");if (pf == NULL){perror("fopen:w:");return 1;}//拷贝文件//一边读一边写,char ch = 0;//这里赋值给,ch 。ch while ((ch = fgetc(ps)) != EOF){fputc(ch, pf);}fclose(ps);fclose(pf);ps = NULL;pf = NULL;return 0;
}
//data 原始被拷贝文件
// 写文件 w把文件创建 =ss 负责接收
//读取创创建的文件  ps读取文件
//
//拷贝文件
//data_copy 拷贝文件到这个文件里面  
// pf 创建被拷贝的文件 首先创建 data_copy的文件 w的形式写进去
// 
// 
// 循环 把写入的data的字符 输入到data_copy里面  
// 首先是读取 也就是 fgetc 读取到eof之前都可循环
// 然后就是输入字符 也就是fputc函数 
// 循环输入 
// 这里是把 循环输出的函数 遍历 赋值给ch
// 此时 也就是fputc(ch,pf)
// 也就是把ch里面的遍历字符 输入到data_copy 也就是pf
//完成作业

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/784257.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RedisDesktopManager 安装

简介&#xff1a;安装redis可视化工具 一、下载压缩包 Redis 可视化工具 链接&#xff1a;https://pan.baidu.com/s/1P2oZx9UpQbXDsxJ3GPUeOQ 提取码&#xff1a;6rft Redis 命令窗口版本 链接&#xff1a;https://pan.baidu.com/s/1mIuxCEWwD__aoqp1Cx8MFQ 提取码&#xf…

Lucene及概念介绍

Lucene及概念介绍 基础概念倒排索引索引合并分析查询语句的构成 基础概念 Document&#xff1a;我们一次查询或更新的载体&#xff0c;对比于实体类 Field&#xff1a;字段&#xff0c;是key-value格式的数据&#xff0c;对比实体类的字段 Item&#xff1a;一个单词&#xff0…

Decoupled Multimodal Distilling for Emotion Recognition 论文阅读

Decoupled Multimodal Distilling for Emotion Recognition 论文阅读 Abstract1. Introduction2. Related Works2.1. Multimodal emotion recognition2.2. Knowledge distillation3. The Proposed Method3.1. Multimodal feature decoupling3.2. GD with Decoupled Multimodal …

基于muduo网络库实现的集群聊天服务器

目录 项目内容开发环境安装说明技术介绍项目目录数据库设计项目介绍启动服务器启动客户端注册账号登录成功一对一聊天业务创建群聊业务加入群聊业务群聊业务添加好友业务离线消息存储业务 特殊说明 &#xff01;&#xff01;&#xff01;项目是照着腾讯课堂施磊老师的视频学习&…

docker部署DOS游戏

下载镜像 docker pull registry.cn-beijing.aliyuncs.com/wuxingge123/dosgame-web-docker:latestdocker-compose部署 vim docker-compose.yml version: 3 services:dosgame:container_name: dosgameimage: registry.cn-beijing.aliyuncs.com/wuxingge123/dosgame-web-docke…

How to install JDK on mac

文章目录 1. Install JDK on mac2. zshenv, zshrc, zprofile3. 查看java环境变量配置 1. Install JDK on mac Installation of the JDK on macOS 2. zshenv, zshrc, zprofile How Do Zsh Configuration Files Work? 3. 查看java环境变量配置 open Terminal&#xff0c;cd…

02-JDK新特性-Lambda表达式

JDK新特性 Lambda表达式 什么是Lambda表达式 Lambda表达式是一个匿名代码块&#xff0c;用于简单的传递一段代码片段。 Lambda表达式标准格式 格式&#xff1a;(形式参数) -> {代码块} 形式参数 如果有多个参数&#xff0c;参数只见用逗号隔开&#xff1b;如果没有&…

【Linux 10】环境变量

文章目录 &#x1f308; Ⅰ 命令行参数⭐ 1. main 函数的参数⭐ 2. main 函数参数的意义⭐ 3. 查看 argv 数组的内容⭐ 4. 命令行参数结论⭐ 5. 为什么要有命令行参数⭐ 6. 命令行参数传递由谁执行 &#x1f308; Ⅱ 环境变量基本概念⭐ 1. 常见环境变量 &#x1f308; Ⅲ 查看…

macOS Catalina for mac (macos 10.15系统)v10.15.7正式版

macOS Catalina是苹果公司专为麦金塔电脑推出的桌面操作系统&#xff0c;是macOS的第16个主要版本。它继承了苹果一贯的优雅与高效&#xff0c;不仅引入了分割视图和侧边栏&#xff0c;还带来了全新的音乐和播客应用&#xff0c;极大地提升了用户体验。在隐私保护和安全性方面&…

【Laravel】07 快速套用一个网站模板

【Laravel】07 快速套用一个网站模板 1. 新增post表2.补充 &#xff1a;生成Model、Controller、迁移文件3. 使用php artisan tinker4. 网站模板下载 课程地址 1. 新增post表 在Model中创建Post (base) ➜ example-app php artisan make:model Post Model created successfu…

练习3-2 计算符号函数的值

对于任一整数n&#xff0c;符号函数sign(n)的定义如下&#xff1a; 请编写程序计算该函数对任一输入整数的值。 输入格式: 输入在一行中给出整数n。 输出格式: 在一行中按照格式“sign(n) 函数值”输出该整数n对应的函数值。 输入样例1: 10 输出样例1: sign(10) 1 输入样例…

pytest--python的一种测试框架--pytest常用断言类型

一、pytest常用断言类型 等于: 不等于&#xff1a;&#xff01; 大于&#xff1a;> 小于&#xff1a;< 属于&#xff1a;in 不属于&#xff1a;not in 大于等于&#xff1a;> 小于等于&#xff1a;< 是&#xff1a;is 不是&#xff1a;is not def test_two():ass…

Java_21 完成一半题目

完成一半题目 有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种知识点类型。 示例…

【Spring Boot 源码学习】ConditionEvaluationReport 日志记录上下文初始化器

《Spring Boot 源码学习系列》 ConditionEvaluationReport 日志记录上下文初始化器 一、引言二、往期内容三、主要内容3.1 源码初识3.2 ConditionEvaluationReport 监听器3.3 onApplicationEvent 方法3.4 条件评估报告的打印展示 四、总结 一、引言 上篇博文《共享 MetadataRe…

cuda cudnn pytorch 的下载方法(anaconda)

文章目录 前言cuda查看当前可支持的最高cuda版本显卡驱动更新下载cuda cudnnpytorch配置虚拟环境创建虚拟环境激活虚拟环境 1.直接下载2.conda 下载(清华源&#xff0c;下载速度慢的看过来)添加清华镜像channel下载下载失败 下载失败解决办法1.浑水摸鱼&#xff0c;风浪越大鱼越…

五、Yocto集成QT5(基于Raspberrypi 4B)

Yocto集成QT5 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第五篇文章&#xff1a; 一、yocto 编译raspberrypi 4B并启动 二、yocto 集成ros2(基于raspberrypi 4B) 三、Yocto创建自定义的layer和image 四、Yocto创建静态IP和VLAN 本章节实操代码请查看github仓库&…

数据可视化-Python

师从黑马程序员 Json的应用 Json的概念 Json的作用 Json格式数据转化 Python数据和Json数据的相互转化 注&#xff1a;把字典列表变为字符串用dumps,把字符串还原回字典或列表用loads import json#准备列表&#xff0c;列表内每一个元素都是字典&#xff0c;将其转化为Json …

python实战之常用内置模块

一. 数学计算模块(math) 二. 日期时间模块(datetime) 1. datetime类 datetime类的常用方法 2. date类 1. date类的常用方法 3. time类 4. 计算时间跨度类(timedelta) 5. 日期时间与字符串相互转换 1. 日期和时间格式控制符 三. 正则表达式模块(re) 正则表达式指预先定义好一个’…

CCF-CSP26<2022-06>-第1/2/3题

202206-1 归一化处理 题目&#xff1a;202206-1 题目分析&#xff1a; 给出了数学上归一化的数学公式&#xff0c;直接按照要求完成即可。 AC代码&#xff1a; #include <bits/stdc.h> using namespace std; int main() {int n;cin >> n;double a[n];double s…

吴恩达:现在做GPT-4智能体,或将提前达到GPT-5效果|钛媒体AGI

斯坦福大学客座教授吴恩达&#xff08;Andrew Ng&#xff09;© 林志佳 美国斯坦福大学教授吴恩达&#xff08;Andrew Ng&#xff09; 人工智能智能体&#xff08;AI Agents&#xff09;似乎将引领 AI 行业新的发展趋势。 近日红杉资本&#xff08;Sequoia&#xff09;在…