赞
踩
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
———————————————————————————————————————————
———————————————————————————————————————————
———————————————————————————————————————————
二进制编译器的方式打开 二进制文件,二进制文件是我们不能直接看懂的文件
文本文件就是肉眼看得懂的
———————————————————————————————————————————
文件使用流程是,打开 读写 关闭
并且文件的使用是需要依靠媒介的,也就是流
就比如你需要开电视,你不可能是用手把电视打开,你还得跑过去,很麻烦,所以我们发明了遥控器,这个遥控器也就是中间媒介,不需要你大费周章的再去开电视,只需要遥控器一按,就打开了。
下面进行图解举例。
———————————————————————————————————————————
因为需要流,所以需要文件指针
在C语言中,文件操作是通过所谓的“流”来进行的,而文件指针就是这种流的抽象表示。FILE
结构体是C标准库中定义的一个数据结构,它用于封装关于文件的信息和用于操作文件的数据。
文件指针通常是指向FILE
结构体的指针变量,它用于表示一个打开的文件流。通过文件指针,您可以执行诸如读取、写入、定位和关闭文件等操作。
当您使用fopen
函数打开一个文件时,它会返回一个FILE
*类型的指针,这就是文件指针。然后,您可以使用这个指针来调用其他文件操作函数,如fread
、fwrite
、fgets
、fputs
、fprintf
等
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打开文件,配合使用
打开文件需要用流,也就是一个介质,
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
fopen` 和 `fclose` 是C语言中用于文件操作的两个基本函数。
`fopen` 函数用于打开一个文件,并返回一个指向该文件的指针。如果打开文件失败,`fopen` 会返回 `NULL`。
函数原型:
- ```c
- FILE *fopen(const char *path, const char *mode);
- ```
参数:
- `path`: 要打开的文件的路径。
- `mode`: 文件的打开模式(例如:`"r"` 读取模式,`"w"` 写入模式,`"a"` 追加模式等)。
返回值:
如果成功,返回一个指向 `FILE` 对象的指针。
如果失败,返回 `NULL`。
——————————————————————————————————————————
`fclose` 函数用于关闭由 `fopen` 函数打开的文件。在关闭文件后,相关的文件指针也会被清空,此后不能再使用该指针进行文件操作。
函数原型:
- ```c
- int fclose(FILE *stream);
- ```
- `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,这两个函数没有详细介绍就说了一下语法格式的问题
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
fputs(const char *str, FILE *stream):将一个字符串写入文件。
但是这里只能写入一个字符单次
——————————————————————————————————————————
——————————————————————————————————————————
读文件,这里需要打印的话需要读取文件,然后才能打印
代码,这这里补充说明一下,fputc函数的使用只能一次写一个字符,要么就是循环输入,并不能直接输入字符串
——————————————————————————————————————————
- #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;
- }

我们发现写进去是没有问题的
——————————————————————————————————————————
- #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);//我们预计写入a
- fputc('bcd', pf);//我们预计写入bcd
-
-
- fclose(pf);
- pf = NULL;
- return 0;
- }

这里我们发现,这里不能输入字符串,还是只能输入一个字符
——————————————————————————————————————————
- #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输入字符是连续输入的
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
语法格式getc函数是C语言中的标准库函数之一,用于从指定的文件流中逐个字符地读取字符。它的函数原型如下:
int fgetc(FILE *stream)
上面我们描述过函数需要
fopen(打开)+读取+打印
中间可能还有写入等等,但是基本上是步骤是这个步骤
——————————————————————————————————————————
getc函数正常读取结束返回的是读取到的字符值。返回值是int类型,范围是0到255,或者是EOF(-1),表示读取结束。
-1 本质是整数 所以返回类型需要是整形
当你使用 fgetc
时,以下规则适用:
如果成功读取一个字符,fgetc
返回该字符的 ASCII 码值。在 ASCII
表中,控制字符(如换行符 \n
、回车符 \r
等)和空格字符也有对应的数值。
如果读取遇到文件末尾(即文件中再也没有字符可以读取),fgetc
返回 EOF
。在 C 标准库中,EOF
定义为 -1
。
如果读取失败(例如,文件指针无效或文件无法打开),fgetc
也会返回 EOF
。
请注意,fgetc
函数只能读取一个字符,而不是字符串。如果你需要读取多个字符,你需要循环调用 fgetc
或者使用其他函数如 fgets
,后者可以读取一行文本。
——————————————————————————————————————————
一个字符一个字符的读取
如果需要所有内容一起读取
那么你需要进行循环读取,读取的字符最好存起来,不等于eof 也就是继续循环,等于的时候也就是停止循环,写一个字符读取一个字符 写一堆字符 读取一堆字符。
——————————————————————————————————————————
- 当你使用 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 也可以是int
- int ch = 0;
- ch =fgetc(ps);
- printf("%c ", ch);
-
- //循环一次进行读取 ,这里你可以用while,也可以用while
-
- fclose(ps);
- pf = NULL;
- return 0;
- }
-
-

可以看到只是读取一个字符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);
- //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 也可以是int
- int 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;
- }
-
-

——————————————————————————————————————————
- #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 也可以是int
- int 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循环好用,所以不详细说明了
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
如下所示:
- ```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
———————————————————————————————————————————
- #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;
- }

这里我们可以发现,我们不仅可以写入字符串,还可以写入文本
——————————————————————————————————————————
- #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` 函数用于从文件读取一行文本。其语法如下:
- ```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
———————————————————————————————————————————
- #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之前可以读取全部
———————————————————————————————————————————
- #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字符直到读取完毕遇见NULL
- char arr[1000] = { 0 };//这里是字符串 或者长的文本,所以接收的时候,需要给一个数组,不能给一个变量
- while (fgets(arr, 100, ps) != NULL)
- {
- printf("%s ", arr);
- }
- fclose(ps);//关闭文件
- ps = NULL;
-
- return 0;
- }

这里特地我给出100字节,当然的读取不完的,这里说明单次读取只能读取一行
循环读取可以不遇见NULL之前可以读取全部
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
两个函数是一样的
打开文件
写文件 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;
- }

——————————————————————————————————————————
同理这个和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;
- }

- int val = 0;
- int ret = fscanf(fout, "%d", &val);
变量 val
和 ret
的作用如下:
val
:这是一个整型变量,用来存储从文件中读取的整数值。在 fscanf
调用之前,val
被初始化为 0。这个初始值是任意的,因为 fscanf
会用从文件中读取的值来覆盖 val
的当前值。val
的地址被传递给 fscanf
,因为 fscanf
需要一个变量的地址来存储读取的数据。
ret
:这是一个整型变量,用来存储 fscanf
函数的返回值。fscanf
返回成功匹配并读取的项数。在这个例子中,如果成功从文件中读取了一个整数值到 val
,ret
将被赋值为 1。如果读取失败或者读取到的不是整数值,ret
将被赋值为 0 或者 EOF(文件结束标志)。如果 ret
的值不是 1,通常需要进行错误处理。
fout
:这是一个指向 FILE
对象的指针,代表了已经打开的文件流。fscanf
通过这个文件流从文件中读取数据。
———————————————————————————————————————————
适用于所有的输出流,可以打印在屏幕上面
也就是你可以用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
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语法说明
这里是 从结构体读取数据
这里是从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经常使用,就不详细举例,直接进行说明。
在C语言中,printf、fprintf、sprintf、scanf、sscanf和fscanf是用于输入和输出数据的函数。下面是它们的区别和通常的使用场景:
格式化的数据就是带有格式的数据
比如整形 字符 浮点型
看到结构体不方便 需要转化为字符串 那就是 sprintf
需要转化回来 那就用sscanf, fscanf
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
在 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()` 函数是 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` 函数是 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个字节那一个字节,那么你就可以使用这个函数,并且使用读取一个字节的函数打印出来。
如果你需要的是,从前往后第三个字节之后的字节,那么你就可以使用这个函数,配套使用读取函数,进行循环读取打印即可。
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
在 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;
- }

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
语法格式
在 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 函数时,可以进行以下操作:
请注意,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` 函数用于在文件读取操作中判断是否到达文件末尾。如果到达文件末尾,则返回非零值;否则返回零。
语法格式如下:
- ```c
- #include <stdio.h>
- int feof(FILE *stream);
- ```
`stream` 是指向 `FILE` 对象的指针,该 `FILE` 对象标识了要检查的流。通常,这个参数是通过 `fopen` 函数返回的。
函数返回值:
- 如果已到达流 `stream` 的文件末尾,则返回非零值。
- 如果 `stream` 未打开或不是一个有效文件流,则行为未定义。
- 如果没有到达文件末尾,则返回零。
在使用 `feof` 函数时,通常与读取操作配合使用,例如 `fread` 或 `fgets`,以检查是否在读取过程中到达文件末尾。
简单的说 是来根据返回值来进行判断的
fgetc 在读取到文件末尾时会返回 EOF,这可以通过比较 ch 和 EOF 来判断是否到达文件末尾。在大多数实现中,EOF 是一个非零值
———————————————————————————————————————————
这个不是判断文件是不是结束 是已经结束判断的原因是什么
是结束了 ?还是出错了?
如果是 正常读取结束那么就会进行判定,走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
- //完成作业

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。