文件
文件概念
磁盘文件:指的是相关数据的集合;存储在外部介质上,如磁盘上,使用时才会调入内存中,如 a.txt
设备文件:在操作系统中将每一个输入输出设备看作一个文件,把他们的输入输出看作对磁盘文件的读写. 如 stdio,stdout.
键盘:标准输入文件,C语言中使用 stdio流 表示.
屏幕:标准输出文件,C语言中使用 stdout流 表示.
Linux系统中设备文件都在/dev目录下
缓存区
对文件的读写要经过缓冲区
缓冲区的分类:
1.行缓冲 : 标准io库函数向标准输出设备(屏幕)输出时,是 行缓冲,如printf(),等
刷新行缓冲的方法:
- 缓冲区有换行符
- 缓冲区满了
- 人为刷新缓冲区通过fflush函数
- 程序正常结束时
2.全缓冲 : 标准库函数向普通文件中读写数据时,是全缓冲
刷新全缓冲的方法:
- 缓冲区满了
- 人为刷新缓冲区通过fflush函数
- 程序正常结束时
3.无缓冲 : 通过系统调用时是 无缓冲
文件分类与字符集
文件分类 : 文本文件(字符) 与二进制文件(0/1值, 程序,视频,图像等);
文本文件:字符集(ACSLL,Unicode,UTF-8,GBK/GB2312,ISO-8859-1)
- ASCLL码:计算机的第一套字符集,最早有128个字符组成,每个字符占一个字节
- Unicode是第一套国际化字符集编码,每个字符占两个字节,中文编码区间为\u4e00-\u9fa;
- UTF-8 是第二套国际化字符集编码,每个中文字符占三个字节,英文占一个字节;
- GBK/GB2312是中国的字符集编码,中文字符占两个字节,英文字符占一个字节
文件操作函数
fopen函数与fclose函数
FILE * fopen (const char filename,const charmode);
第一个参数是文件名或者文件地址(相对地址或者绝对地址)
第二个参数是文件模式,r 只读, w 只写, a 追加 , +扩展读写操作,与rwa结合使用.
fgetc函数与fputc函数 --单字符的读写
int fgetc(char * filename) //获取单字符的数值,光标处于尾部返回EOF,其他字符返回数值
int fputc(int c,char *filename) //传入数值c的单字符,返回数值c,失败返回-1即EOF
代码示例:
#include<stdio.h>
int main()
{
FILE *p =fopen("a.txt","r+");
// r+模式,光标定义到开始处,先写入一个A覆盖第一个字符,后输出光标后的所有字符,所以输出中没有第一个字符
//fopen()函数,打开文件到内存中,模式为读写,也可以为W+
int c=65;
int s=fputc(c,p);
//fputc函数,将c字符传入到文件指针p的空间中
while((c=fgetc(p))!=EOF)
//fgetc函数,将内存中的字符以数值传出来赋值给c
{
printf("%c\n",c);
}
fclose(p); //文件关闭,从内存中转到磁盘文件中
return 0;
}
结果:
fgets函数与fputs函数—字符串的读写
char * fgets(char *str,int size,FILE *filename)//将文件filename中size个字符传出到str中,成功返回str中的首地址,失败返回NULL
int fputs(const char *str,FILE *filename)//将str中的内容传入到文件中,成功返回非负值,失败返回-1;
#include<stdio.h>
int main()
{
FILE *p =fopen("a.txt","r+");
//fopen()函数,打开文件到内存中,模式为读写,也可以为W+
char str[120];
while(fgets(str,5,p)!=NULL)
//读取字符串,每次从p读取5字节的字符保存到str中
//fgets函数,将内存中的字符以数值传出来赋值给c
{
printf("%s\n",str);//字符数组中的内容每次被赋值后都会覆盖
}
printf("%s\n",str);//所以str数组中内容为最后一次的输入
return 0;
}
#include<stdio.h>
int main()
{
FILE *p =fopen("a.txt","r+");
//fopen()函数,打开文件到内存中,模式为读写,也可以为W+
char str[120]={'a','s','d','f'};
int len =fputs(str,p); 返回值为1;将asdf保存至文件中
printf("%d\n",len);
fclose(p);
printf("%s\n",str);//所以str数组中内容为最后一次的输入
return 0;
}
fread函数与fwrite函数–二进制文件的读写
二进制文件-(结构体变量,文件整体)
int fread(void *dest ,int struct_size, int n,FILE *filename)
从文件中读取n块size大小的结构体,保存到dest中,成功返回块数,失败返回0;
int fwrite(void *dest ,int struct_size, int n,FILE *filename)
从dest中将n块size大小的结构体写入到文件中,成功返回块数,失败返回0;
#include<stdio.h>
typedef struct stu
{
long sn;
char name[50];
char sex[5];
int age;
} STU;
int main()
{
STU s1 = {1001, "jack", "男", 20};
// 将s1和s2写入到文件stu.dat文件中
FILE *f = fopen("a.txt", "wb");
size_t n = fwrite(&s1, sizeof(STU), 1, f);
printf("%ld \n", n);
fclose(f);
return 0;
}
fprintf函数与fscanf函数
fprintf(文件指针,格式字符串,输出表列); // 将格式化的字符串写入到文件中
fscanf (文件指针,格式字符串,输入表列); // 从文件(当前光标位置)中读取格式化中的占位的数
据
#include <stdio.h>
int main(int argc, char const *argv[])
{
int sn = 1001;
int age = 20;
char name[] = "disen";
float score = 98.5;
// 将sn,age,name和score等数据按某一个格式写入到文件尾部
FILE *f = fopen("c.txt", "w");
fprintf(f, "%d %s %d %f\n", sn, name, age, score);
fclose(f);
return 0;
}
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *f = fopen("c.txt", "r");
// 按一定的格式从文件中读出数据
int sn, age;
char name[50];
float score;
int n = -1;
// 从文件中读取格式化字符串的数据,如果返回-1表示读取结束
// 【要求】格式化字符串中的多个数据建议使用空格分隔
while ((n = fscanf(f, "%d %s %d %f\n", &sn, name, &age, &score)) != -1)
{
printf("--->%d,%d,%s,%f\n", sn, age, name, score);
}
fclose(f);
return 0;
}