如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,而文件可以帮助我们永久保存数据,防止丢失
从功能的角度分类:
分为 程序文件 和 数据文件
包括 源文件(后缀.c), 目标文件(windows环境后缀.obj), 可执行文件(windows环境后缀.exe)
文件的内容不一定是程序,而是程序运行时读写的数据
从数据组织的角度分类:
分为 二进制文件 和 文本文件
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
举例
数字 10000
数据的输入和输出都需要依靠外部设备,因为不同外部设备输入输出不同,为了方便操作方便,引出流的概念
进行输入输出的时候,都需要打开流
实际上,当我们使用printf 和 scanf 这样输入输出的函数时,已经打开了流,这个流就是标准流(本质是对于键盘的输入输出)
C语言启动时 ,会打开的三个标准流
a. stdin --- 标准输入流
b. stdout -- 标准输出流
c. stderr -- 标准错误流
stdin、stdout、stderr 三个流的类型是: FILE* ,通常称为文件指针,C语言可以通过文件指针来维护流
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件信息,这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名 FILE
每当打开一个文件的时候,系统会根据文件的情况自动创建一个 FILE结构的变量,并填充其中的信息,通过文件指针变量能够间接找到与它关联的文件
fopen 函数来打开文件
跳转网站
注意事项:
- FILE * fopen(const char *filename , const char * mode)
返回类型 : FILE * (返回文件的地址)
? ? ?2. 参数 filename 和 mode
filename 是指 文件的名字 (如:“test.txt”)
mode 是指使用方式
参数类型都是 char *
? ? 3.引用头文件
<stdio.h>
? ? 4. 打开失败
文件可能出现打开失败的情况,返回的就是空指针(一般情况下,我们需要去判断)
举例
FILE * fopen("test.txt","w");
fclose 函数来关闭文件
跳转网站
注意事项:
- FILE * fopen(const char *filename , const char * mode)
返回类型 : int
? ? ?2. 参数 stream
stream 是流的指针
参数类型是 FILE*
? ? 3. 引用头文件
<stdio.h>
举例
#include<stdio.h> int main() { FILE *pa = fopen("test.txt", "w"); if (pa == NULL) { perror("fopen"); } fclose(pa); return 0; }
运行结果:
a.? ? "r" (只读):
打开一个已经存在的文件(没有这个文件就会报错)
举例
#include<stdio.h> int main() { FILE *pa = fopen("test.txt", "r"); if (pa == NULL) { perror("fopen"); } fclose(pa); return 0; }
如果没有这个文件,就会报错
b.? ? "w"(只写):
打开一个文件,如果没有就新创建一个文件,结束程序时,下一次还使用 “w”方式打开文件,里面的内容不会保存
举例
#include<stdio.h> int main() { FILE *pa = fopen("test.txt", "w"); if (pa == NULL) { perror("fopen"); } fclose(pa); return 0; }
这是新建的文件夹
c.? ?"rb"(二进制读)
打开一个已经存在的文件(没有这个文件就会报错)
d.? ? “wb"(二进制写)
打开一个文件,如果没有就新创建一个文件
字符输入函数 (相当于从流中读取数据)
跳转网站
注意事项:
返回类型 : int (返回的是字符的ASCLL码值)
? ? 2. 参数 stream
stream 是流的指针(适用于所有流)
参数类型是 FILE *
? ? 3. 引用头文件
<stdio.h>
举例
此时文件里面的内容:
#include<stdio.h> int main() { FILE *pa = fopen("test.txt", "r"); if (pa == NULL) { perror("fopen"); } int ret = fgetc(pa); printf("%c ", ret); fclose(pa); return 0; }
运行结果:
#include<stdio.h> int main() { FILE *pa = fopen("test.txt", "r"); if (pa == NULL) { perror("fopen"); } int ret = fgetc(pa); fputc(ret, stdout); fclose(pa); return 0; }
运行结果:
字符输出函数 (相当于向流中写入数据)
跳转网站
注意事项:
返回类型 : int (返回的是字符的ASCLL码值)
? ? 2. 参数 character 和 stream
character 是 字符的ASCLL码值
stream 是流的指针(适用于所有流)
参数类型分别是 int 和 FILE *
? ? 3. 引用头文件
<stdio.h>
举例
#include<stdio.h> int main() { FILE *pa = fopen("test.txt", "w"); if (pa == NULL) { perror("fopen"); } int ret = fputc('A', pa); fclose(pa); return 0; }
文本行输入函数(相当于从流中读取数据)
跳转网站
注意事项:
返回类型 : char *(返回字符的地址)
? ? 2. 参数 str ,num, stream
str 是数组的地址
num 是读取数据的个数(实际上读取的个数是 num - 1,因为它还会放入一个'\0')
stream 是流的指针(适用于所有流)
参数类型分别是 char* , int , FILE *
? 3. 引用头文件
<stdio.h>
举例
此时文件的内容:
#include<stdio.h> int main() { char ch[10]; FILE *pa = fopen("test.txt", "r"); if (pa == NULL) { perror("fopen"); } fgets(ch,3,pa); printf("%s", ch); fclose(pa); return 0; }
运行结果:
文本行输出函数(相当于向流中写入数据)
跳转网站
注意事项:
返回类型 : int (返回字符的地址)
? ? ?2. 参数 str , stream
str 是数组的地址
stream 是流的指针(适用于所有流)
参数类型分别是 char* , FILE *
? ? 3. 引用头文件
<stdio.h>
举例
#include<stdio.h> int main() { char ch[] = "abcde"; FILE* pa = fopen("test.txt", "w"); if (pa == NULL) { perror("fopen"); return 1; } fputs(ch,stdout); fclose(pa); return 0; }
运行结果:
#include<stdio.h> int main() { char ch[] = "abcde"; FILE* pa = fopen("test.txt", "w"); if (pa == NULL) { perror("fopen"); return 1; } fputs(ch,pa); fclose(pa); return 0; }
格式化输入函数 (相当于从流中读取数据)
跳转网站
注意事项:
stream 是流的指针(适用于所有流)
参数类型是 FILE *
? ? ?3.引用头文件
<stdio.h>
举例
此时文件的内容:
#include<stdio.h> int main() { char ch[10] ; FILE* pa = fopen("test.txt", "r"); if (pa == NULL) { perror("fopen"); return 1; } fscanf(pa, "%s", ch); return 0; }
格式化输出函数 (相当于向流中写入数据)
跳转网站
注意事项:
stream 是流的指针(适用于所有流)
参数类型是 FILE *
? ? 3. 引用头文件
<stdio.h>
举例
此时文件的内容:
#include<stdio.h> int main() { char ch[10] = "AAACCC"; FILE* pa = fopen("test.txt", "w"); if (pa == NULL) { perror("fopen"); return 1; } fprintf(pa,"%s", ch); return 0; }
现在文件的内容:
二进制输入(相当于从流中 以二进制的形式 读取 数据)
跳转网站
注意事项:
返回类型 :size_t
? ? ?2. 参数 ptr ,size , count ,stream
ptr 可以是任何类型的指针
size 是 指针所指对象每个元素的大小
count 是 指针所指对象每个元素的个数
stream 是流的指针(适用于文件)
参数类型是 void *,size_ t, size_ t ,FILE *
? ? 3. 引用头文件
<stdio.h>
举例
#include<stdio.h> int main() { char ch[10]; FILE* pa = fopen("test.txt", "r"); if (pa == NULL) { perror("fopen"); return 1; } fread(ch,sizeof(int),1,pa); return 0; }
二进制输出(相当于向流中 以二进制的形式 写入 数据)
跳转网站
?
注意事项:
返回类型 :size_t
? ? ?2.?参数 ptr ,size , count ,stream
ptr 可以是任何类型的指针
size 是 指针所指对象每个元素的大小
count 是 指针所指对象每个元素的个数
stream 是流的指针(适用于文件)
参数类型是 void *,size_ t, size_ t ,FILE *
? ? 3. 引用头文件
<stdio.h>
举例
#include<stdio.h> int main() { int ch[] = {1,2,3,4}; FILE* pa = fopen("test.txt", "w"); if (pa == NULL) { perror("fopen"); return 1; } fwrite(ch,sizeof(int),4,pa); return 0; }
此时文件的内容:
因为 输入是以二进制的形式输入,而用文本编译器编辑,所以结果会与之前不同