1.文件
磁盘上代码文件就是文件。从功能上能够把文件分为程序文件,数据文件。
2.程序文件
源程序文件(.c),目标文件(Windows:.obj/Linux:.o),可执行文件(.exe)。
3.数据文件
程序运行时读写的数据所在的文件。根据数据的组织形式可分为二进制文件和文本文件。
3.1.二进制文件
数据在内存中以二进制的形式存储,不加转换的输出到外存的文件中。
eg:10000-->00000000 0000000 00100111 00010000
3.2.文本文件
以ASCII字符的形式存储,转化成ASCII码的形式输出到外存文件中。
eg:10000-->00110001 00110000 00110000 00110000 00110000
4.文件名
一个文件要有一个唯一的文件标识,即文件名。
文件名:文件路径+文件名主干+文件后缀
c:code\test.c.txt-->c:code\是文件路径,test是文件名主干,.c是文件后缀
文件后缀不是必不可少的,其作用是文件的默认打开方式。
5.在VS上打开二进制文件
6.文件的打开和关闭
6.1流和标准流
6.1.1流
流是对输入输出设备的抽象。一般情况下,我们想要向流里写数据,读取数据,都要打开流,然后操作。
6.1.2标准流
stdin:标准输入流,如scanf
stdout:标准输出流,如printf
stderr:标准错误流
6.2文件指针
每个被使用的文件都在内存中开辟了⼀个相应的文件信息区,⽤来存放⽂件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在⼀个结构体变量中。该结构体类型是由系统声明的,取名 FILE。定义一个FILE*的指针变量,能够通过⽂件指针变量能够间接找到与 它关联的⽂件。
6.3文件的打开和关闭
fopen函数用来打开文件
fclose函数用来关闭文件
7.文件的顺序读写
7.1顺序读写函数
7.1.1 fgetc
int main()
{
/*FILE* pw = fopen("text.txt", "w");
if (pw == NULL)
{
perror("fopen");
return 1;
}
fputc('w', pw);
fputc('a', pw);
fputc('n', pw);
fputc('g', pw);*/
FILE* pr = fopen("text.txt", "r");
if (pr == NULL)
{
perror("fopen");
return 1;
}
int ch = fgetc(pr);
printf("%c", ch);
ch = fgetc(pr);
printf("%c", ch);
ch = fgetc(pr);
printf("%c", ch);
/*int ch = 0;
while ((ch = fgetc(pr)) != EOF)
{
printf("%c", ch);
}*/
/*fclose(pw);
pw = NULL;*/
fclose(pr);
pr = NULL;
return 0;
}
7.1.2 fputc
int main()
{
FILE* pw = fopen("text.txt", "w");
if (pw == NULL)
{
perror("fopen");
return 1;
}
fputc('w', pw);
fputc('a', pw);
fputc('n', pw);
fputc('g', pw);
int ch = 0;
while ((ch = fgetc(pr)) != EOF)
{
printf("%c", ch);
}
fclose(pw);
pw = NULL;
return 0;
}
7.1.3 fgets
int main()
{
FILE* pr = fopen("text.txt", "r");
if (pr == NULL)
{
perror("fopen");
return 1;
}
char arr[20] = { 0 };
while (fgets(arr, 10, pr) != NULL)
{
printf("%s", arr);
}
fclose(pr);
pr = NULL;
return 0;
}
7.1.4 fputs
int main()
{
FILE* pf = fopen("text.txt", "a");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fputs("abd", pf);
fputs("\nabd", pf);
fclose(pf);
pf = NULL;
return 0;
}
7.1.5 fscanf
struct S
{
char name[20];
int age;
float score;
};
int main()
{
struct S s = { "zhangsan",19,65.5f };
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 0;
}
//格式化输入函数-fscanf
fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
//打印在屏幕上
//printf("%s %d %f", s.name, s.age, s.score);
fprintf(stdout,"%s %d %f", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}
7.1.6 fprintf
struct S
{
char name[20];
int age;
float score;
};
int main()
{
struct S s = { "zhangsan",19,65.5f };
FILE* pf = fopen("text.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 0;
}
//格式化输出函数-fprintf
fprintf(pf, "%s %d %f", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}
7.1.7 fread
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
FILE* pf = fopen("text1.txt", "rb");
if (pf == NULL)
{
perror("fopen");
return 0;
}
fread(arr, sizeof(arr[0]), 5, pf);
for (int i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
//fprintf(stdout, "%d ", arr[i]);
}
fclose(pf);
pf = NULL;
return 0;
}
7.1.8 fwrite
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
FILE* pf = fopen("text1.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 0;
}
fwrite(arr, sizeof(arr[0]), 5, pf);
fclose(pf);
pf = NULL;
return 0;
}
8.文件的随机读写
8.1 fseek
int main()
{
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 0;
}
int ch = fgetc(pf);
printf("%c\n", ch);
//fseek(pf, 3, SEEK_CUR);//当前位置
//fseek(pf, -3, SEEK_END);//结尾
fseek(pf, 3, SEEK_SET);//起始位
ch = fgetc(pf);
printf("%c\n", ch);
fclose(pf);
pf = NULL;
return 0;
}
8.2 ftell
int main()
{
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 0;
}
int size = 0;
fseek(pf, 0, SEEK_END);//起始位
size = ftell(pf);
printf("%d\n", size);
fclose(pf);
pf = NULL;
return 0;
}
8.3 rewind
int main()
{
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 0;
}
int size = 0;
fseek(pf, 0, SEEK_END);//起始位
size = ftell(pf);
printf("%d\n", size);
rewind(pf);
int ch = fgetc(pf);
printf("%c", ch);//z
fclose(pf);
pf = NULL;
return 0;
}
9.文件读取结束的判定
1.⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
- fgetc 判断是否为 EOF
- fgets 判断返回值是否为 NULL
int main() { FILE* pf = fopen("text.txt", "r"); if (pf == NULL) { perror("fopen"); return 1; } //写 int ch = 0; for (ch = 'a';ch <= 'z'; ch++) { fputc(ch, pf); } //判断是什么原因造成的读取结束 if (feof(pf)) { printf("遇到文件末尾,读取正常结束\n"); return 1; } else if (ferror(pf)) { perror("ferror"); return 1; } return 0; }
2.⼆进制⽂件的读取结束判断,判断返回值是否⼩于实际要读的个数
- fread判断返回值是否⼩于实际要读的个数
enum { SIZE = 5 };
int main(void)
{
double a[SIZE] = {1.,2.,3.,4.,5.};
FILE *fp = fopen("test.bin", "wb"); // 必须⽤⼆进制模式
fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组
fclose(fp);
double b[SIZE];
fp = fopen("test.bin","rb");
size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组
if(ret_code == SIZE) {
puts("Array read successfully, contents: ");
for(int n = 0; n < SIZE; ++n)
printf("%f ", b[n]);
putchar('\n');
} else { // error handling
if (feof(fp))
printf("Error reading test.bin: unexpected end of file\n");
else if (ferror(fp)) {
perror("Error reading test.bin");
}
}
fclose(fp);
}
10.文件缓冲区
是指系统自动地在内存中为程序中每⼀个正在使用的文件开辟⼀块“文件缓冲区”。