文件操作原理
———————————————————————————————————————————
为什么使用文件
———————————————————————————————————————————
什么是文件
———————————————————————————————————————————
二进制文件 和文本文件
二进制编译器的方式打开 二进制文件,二进制文件是我们不能直接看懂的文件
文本文件就是肉眼看得懂的
———————————————————————————————————————————
文件流
文件使用流程是,打开 读写 关闭
并且文件的使用是需要依靠媒介的,也就是流
就比如你需要开电视,你不可能是用手把电视打开,你还得跑过去,很麻烦,所以我们发明了遥控器,这个遥控器也就是中间媒介,不需要你大费周章的再去开电视,只需要遥控器一按,就打开了。
下面进行图解举例。
———————————————————————————————————————————
文件指针
因为需要流,所以需要文件指针
在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打开文件,配合使用
- "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);//我们预计写入a
fputc('bcd', pf);//我们预计写入bcd
fclose(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
时,以下规则适用:
-
如果成功读取一个字符,
fgetc
返回该字符的 ASCII 码值。在ASCII
表中,控制字符(如换行符\n
、回车符\r
等)和空格字符也有对应的数值。 -
如果读取遇到文件末尾(即文件中再也没有字符可以读取),
fgetc
返回EOF
。在 C 标准库中,EOF
定义为-1
。 -
如果读取失败(例如,文件指针无效或文件无法打开),
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 也可以是int
int ch = 0;
ch =fgetc(ps);
printf("%c ", ch);
//循环一次进行读取 ,这里你可以用while,也可以用while
fclose(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 也可以是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;
}
——————————————————————————————————————————
代码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 也可以是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循环好用,所以不详细说明了
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
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字符直到读取完毕遇见NULL
char arr[1000] = { 0 };//这里是字符串 或者长的文本,所以接收的时候,需要给一个数组,不能给一个变量
while (fgets(arr, 100, ps) != NULL)
{
printf("%s ", arr);
}
fclose(ps);//关闭文件
ps = NULL;
return 0;
}
这里特地我给出100字节,当然的读取不完的,这里说明单次读取只能读取一行
循环读取可以不遇见NULL之前可以读取全部
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
文件操作函数的综合使用
#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
//完成作业