江西医疗网站备案前置审批,在国内做跨境电商怎么上外国网站,经典品牌推广文案,怎么做搜索功能网站学习的流程 ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————…
学习的流程 ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
文件操作原理 ———————————————————————————————————————————
为什么使用文件 ———————————————————————————————————————————
什么是文件 ———————————————————————————————————————————
二进制文件 和文本文件 二进制编译器的方式打开 二进制文件二进制文件是我们不能直接看懂的文件 文本文件就是肉眼看得懂的
———————————————————————————————————————————
文件流
文件使用流程是打开 读写 关闭
并且文件的使用是需要依靠媒介的也就是流
就比如你需要开电视你不可能是用手把电视打开你还得跑过去很麻烦所以我们发明了遥控器这个遥控器也就是中间媒介不需要你大费周章的再去开电视只需要遥控器一按就打开了。
下面进行图解举例。 ———————————————————————————————————————————
文件指针
因为需要流所以需要文件指针
在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);filePtrNULLreturn 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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdio.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
#includestdio.h
#includestdlib.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
#includestdio.h
#includestdlib.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
#includestdio.h
#includestdlib.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
#includestdio.h
#includestdlib.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
#includestdio.h
#includestdlib.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是用于输入和输出数据的函数。下面是它们的区别和通常的使用场景
printf printf函数用于将格式化的数据输出到标准输出通常是终端或控制台。它不会在输出字符串的末尾添加换行符所以如果需要换行需要在格式字符串中显式包含\n。示例printf(Hello, World!\n
fprintf fprintf函数用于将格式化的数据输出到任意指定的文件指针FILE *。它可以将数据输出到文件、网络流等。示例FILE *fp fopen(file.txt, w); fprintf(fp, Hello, World!\n); fclose(fp);
sprintf sprintf函数用于将格式化的数据输出到一个字符数组或字符串。简单的说就是转化成字符串格式它不会在输出字符串的末尾添加换行符。示例char buffer[100]; sprintf(buffer, Hello, World!\n); printf(%s, buffer); scanf scanf函数用于从标准输入通常是键盘读取格式化的数据。它等待用户输入并根据指定的格式解析输入的数据。示例int num; scanf(%d, num); printf(You entered: %d\n, num);
sscanf sscanf函数用于从字符串中读取格式化的数据。可以把字符串转化为任何你需要的格式它将字符串中的数据按照指定的格式解析成变量。示例char str[] 1234; int num; sscanf(str, %d, num); printf(You entered: %d\n, num);可以把字符串转化为任何你需要的格式
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必需。每个数据项的大小以字节为单位。大小sizeofarr[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
#includestdio.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
#includestdio.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
#includestdio.h
#includestdlib.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
#includestdio.h
#includestdlib.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 函数时可以进行以下操作
确定当前的文件位置。在读取或写入文件后检查位置是否如预期。在处理大文件时可以利用 ftell 来判断是否已经到达文件末尾。
请注意ftell 返回的值是在调用 fseek 之前或与之关联的文件操作之后的文件位置。如果在 ftell 之后对文件进行任何操作如读取、写入或定位则返回的值将不再准确。
在使用 ftell 时还应当注意平台的差异因为 ftell 的行为可能会受到操作系统和文件系统的影响。
从前到后用于获取当前文件位置指针的位置。这里是9这里返回的是文件的偏移量 代码
#define _CRT_SECURE_NO_WARNINGS 1
#includestdio.h
#includestdlib.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;//这里需要进行一个返回值进行接收sftell(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
#includestdio.h
#includestdlib.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
// 此时 也就是fputcchpf
// 也就是把ch里面的遍历字符 输入到data_copy 也就是pf
//完成作业