一。文件的基本操作
1.常常需要将一些数据输出到磁盘上保存起来,用来以后使用,这就是要用到的磁盘文件
文件名+.+扩展名(表明了类型 例 .cpp表示c++的源文件 .c .o 目标文件.obj .h .doc word 文档)数据比较多,从文件去读,还有存进去,永远保存数据
2.文件最主要的作用是保存数据
3.读取数据:按文件名找到所指的文件,调入内存缓冲区,内存处理速度快,编辑之后一定要保存,保存就是将文件从内存缓冲区放到磁盘里去
存储文件:知道文件名,建立一个文件,有文件名
4.输入操作时:数据从文件流向计算机内存,称为输入流 c语言把键盘称作输入设备,就是输入设备文件,硬件也是文件啦
输出操作时:数据从计算机内存流向文件,称为输出流 结果,中间结果存到磁盘文件,我们说输到显示器,显示器叫做输出设备文件(不会永久保存)
5.c语言把文件作为一个字符/字节序列--数据流来处理(文件存的每一个信息是一个一个的单字符 比如“1234”可以是整数也可以是字符串 如果你以字符形式传进来的话,文件当中就是1234呈现出来四个字符 文本文件,以另外的方式去读就是1234,如果以单字符挨个去读 读出来的就是字符串)
c语言允许你将一个数据按字节存 内存怎么存储方式文件怎么存
文件的存储方式:按逐个字符存起来的形式和按字节存起来的形式
6.printf 自然认为输出到显示器文件
7.文本文件(ASCII码)和二进制文件
数据在内存中是以二进制形式存储的,如果不加转换的输出到外存,就是二进制文件
如果要求在外存上以ASCII码的形式存储,则与需要在存储前进行转换
如果以文本文件存储的文件如果用记事本(能打开的文件的扩展名是.tst的)看到打开就可以清晰的里面的内容,如果以二进制存储的文件以记事本打开,看到的就是乱码,因为它是以内存中的方式存放的
二进制文件怎么才能看到它真正的内容呢?内存中以二进制存,都是0,1之类的
二进制的文件显示到屏幕上就是以文本形式显示的
ASCII文件又叫文本文件或流式文件,每一个字节放一个字符的ASCII码
double 类型的数据在内存中占据8个字节,位数后面再多都存了下来 如果是ASCII码的话每一位都要存起来,五个字符占据五个字节
二。文件的指针及文件的处理流程
1.文件指针: c语言程序使用文件时,通过一个指针变量指向对应的文件信息区(c想处理文件,需先调入文件缓冲区,访问信息,缓冲区的地址在哪里?,我们通过指针,利用fp来访问文件中的所有信息),这个指针变量称为文件指针
FILE * fp
2.处理流程 打开或新建文件-》读或写文件-》关闭文件(把缓冲区文件存到磁盘上了,把指针和文件缓冲区脱钩)
方式打开指文件的打开函数 FILE *fopen("文件名","打开方式") 只读或只写---------按照指定的文件使用打开文件-------成功分配文件缓冲区并返回FILE类型指针-----失败 返回NULL
例:fp=fopen("e:\\program\\input.txt","r")---- 现有的字符串可能看成转义字符,输入键盘读的时候不需要考虑转义字符 rb二进制文件 \\=\=/
char *str="input.txt";
fp=fopen(str,"r");
//会报错的,直接给了个字符串常量
//改成数组
char str[100]="input.txt";
w等同于新建,就算文件里有数据也会弄丢
a文件不丢失,在文件后面继续添加
r如果在磁盘上没有这个文件会打开出错,以w形式打开没有它就给你新建,有也给你新建,如果以a的形式去打开不存在的文件也是新建
文件的关闭函数 int fclose(File *fp)----如果在内存缓冲区断电就一下子没了
功能:关闭fp指定的文件,释放该文件的缓冲区,FILE类型的变量以及文件指针(成功返回0,否则返回非0值)
.如果打开失败,fopen会带回来一个出错信息,带回空指针NULL
常用下面的方式打开一个文件读取数据:
if((fp=fopen("file1","r"))==NULL)//括号不能省略==的优先级高于=
{
printf("cannot open this file\n");
exit(1);//等价于return 0;----exit()函数需要加头文件stdlib.h
}
文件的读写函数 单字符读写函数:fputc和fgetc int fputc(char ch,FILE *fp) 功能:将字符ch写入到文件指针fp所指的文件的当前写指针位置
ch/int fgetc(char ch,FILE *fp) EOF 是文件结束符
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
FILE *fp;
fp=fopen("d:\\abc.txt","w");
if(fp==NULL) {printf("Failed");return 0;}
fputc('a',fp);
fclose(fp);
return 0;
}
字符串读写函数:fputs和fgets 写函数 功能:将字符串str写入到文件指针fp所指向的文件的当前写指针位置
读函数 char *fgets(char *str,int n,FILE *fp)读的这个串你想写到哪里,写到参数里面,字符数组
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
FILE *fp;
fp=fopen("d:\\zz.txt","w");
int a;
if(fp==NULL){printf("file open error");}
else
printf("file open success!\n");
a=fputs("I am zhangna",fp);
printf("%d",a);
fclose(fp);
return 0;
}
格式化读写函数:fprintf和fscanf
注意:fputc/fgetc fputs/fgets fscanf/fprintf这三对操作的都是文本文件,这三对的使用方式不能操作二进制,只能按字符去读
我们希望格式化的读写操作,我们就在屏幕上显示的那样,我们希望输入到文件中也是这样的方式输出的(fprintf就是文件的内容显示在屏幕上也很好看)
以前我们用scanf是从键盘读,从printf是从屏幕输出。现在我们用fscanf是从文件读,fprintf是输入到文件中
写函数:int fprintf(fp,格式控制块,输出项参数表)
功能:将输出项按照指定格式写入fp所指向的文件中 往文件中写入 若成功返回实际写入的字节数(两个整型8个字节,) 失败:EOF
写函数:int fscanf(fp,格式控制块,输出项参数表)
功能:从文件中读给变量赋值 成功返回实际读出的数据项个数
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
FILE *fp;
int a;
float f;
fp=fopen("d:\\abc.txt","r");
if(fp==NULL) {printf("Failed");return 0;}
fscanf(fp,"%d%f",&a,&f);
printf("%d %f",a,f);
fclose(fp);
return 0;
}
实现了文件的格式化输出了
数据块读写函数:fwrite和fread (二进制的文件)
结构体类型包含很多成员,如果fprintf一个一个里写入的话很困难就引入了结构块读写函数
注意:用fprintf向文件当中写的话以空格分割,因为不容易从文件中读出来
从文件中读写一块数据使用数据块读写函数,文件必须二进制文件打开(rb,wb)
系统访问二进制文件比文本文件快
写二进制的文件
读二进制的文件
文件结束测试函数 一般不使用 因为它会在文件中多读出来一个没有用的(文件结束标志 它把文件结束标志也认为是文件里的内容了) 利用函数返回标记 例fscanf("%c")
文件的顺序读写例题:
1,读取d:\aa.txt文件中的若干数据(个数不超过100)进行显示,按照从小到大的顺序排序后存到d:\bb.txt文件中
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void output(int a[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
void sort(int a[],int n)
{
int i,j,t;
for(i=0;i<n-1;i++)
for(j=0;j<n-i-1;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
int main()
{
FILE *fa=fopen("d:\\aa.txt","r");
FILE *fb=fopen("d:\\bb.txt","w");
int a[100],i,n=0;
if(fb==NULL||fa==NULL)
{
printf("file open error!");
return 0;
}
else
printf("file open success!\n");
while(fscanf(fa,"%d",a+n)!=-1)n++;
output(a,n);
sort(a,n);
for(i=0;i<n;i++)
fprintf(fb,"%d ",a[i]);
fclose(fa);
fclose(fb);
}
2.从键盘中输入n个学生的信息保存到文件中,要求以二进制文件格式存入,文件名为:d:\\stu.dat 学生信息包括学号,姓名,年龄和C语言课程的成绩
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define LEN sizeof(Student)
typedef struct student
{
int id;
char name[20];
int age;
double score;
}Student,*SP;//用结构题有好处,结构体排序
int main()
{
FILE *fp=NULL;
SP p=NULL,q;
int i,n;
scanf("%d",&n);
char s1[100]="d:\\studn.dat";
q=p=(SP)malloc(n*LEN);
for(i=0;i<n;i++,p++)
{
scanf("%d%s%d%lf",&p->id,p->name,&p->age,&p->score);
}
if((fp=fopen(s1,"wb"))==NULL)
{
printf("Error\n");return 0;
}
fwrite(q,LEN,n,fp);
if(fclose(fp)==0)
printf("save success");
free(q);
return 0;
}
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define LEN sizeof(Student)
typedef struct student
{
int id;
char name[20];
int age;
double score;
}Student,*SP;//用结构题有好处,结构体排序
int main()
{
FILE *fp=NULL;
SP p=NULL,q;
char s1[100]="d:\\studn.dat";
int i,n=0;
//scanf("%d",&n);
q=p=(SP)malloc(10*LEN);
if((fp=fopen(s1,"rb"))==NULL)
{
printf("Error\n");
return 0;
}
while(fread(q,LEN,1,fp)==1)
{
n++;
q++;
}
q=p;
for(i=0;i<n;i++,q++)
{
printf("%d\n",q->id);
}
//if(fclose(fp)==0)
//printf("save success");
free(q);
return 0;
}