Calloc函数用来动态分配内存,与malloc不同的是可以把动态分配的所有存储区内容设置成0 。 (相当于数组初始化)
使用calloc标准函数需要包含stdlib.h头文件
calloc函数需要两个参数,第一个参数表示要分配的存储区个数,第二个参数表示单个存储区的大小
calloc函数的返回值是分配好的第一个存储区的地址,如果分配内存失败,则返回值是NULL,与malloc一样
realloc函数用来调整一段动态分配内存的大小(尽量少用)
文件操作:
文件都以二进制方式保存信息,分为文本文件和二进制文件
文本文件中所有二进制数据都对应字符
除了文本文件以外的所有文件叫做二进制文件
文本文件也可以当做二进制文件进行操作
文件操作基本步骤:
1:打开文件(fopen)
2::操作文件(fread / fwrite)
3:关闭文件(fclose)
两种操作方式
1#include<stdio.h>
2int main(){
3 FILE*p_file=fopen("a.txt","w");
4 /* if(p_file){
5 //...操作文件
6 fclose(p_file);
7 p_file=NULL;
8
9 }*/
10 if(!p_file){
11 printf("打开文件失败\n");
12 return 0;
13 }
14 //编写程序操作文件
15 fclose(p_file);
16 p_file=NULL;
17 return 0;
18 }
fopen需要两个参数
第一个参数表示要打开文件的路径
第二个参数表示打开文件的方式(决定程序中可以对文件做什么操作)
文件打开方式有如下选择
“r” 只能查看文件内容,不能修改文件内容,要求文件必须已经存在,如果不存在则打开失败
“r+” 比r 多了修改文件内容的功能
“w” 只能修改内容,不能查看,并且只能从文件头开始修改。如果文件不存在就创建文件,如果文件已经存在,就把文件内容删除
“w+”比“w”多了查看内容的功能
“a ” 只能修改,不能查看,修改方式是在文件末尾追加新内容。如果文件不存在就创建文件,如果文件存在,不会修改文件原有内容
“a+” 比“a”多了查看功能
“b” 可以和前面六个中任何一个混合使用,这种打开方式表示要以二进制的方式操作文件
fopen返回值是一个地址,把它记录在文件指针里,程序中只能用文件指针代表文件
fopen函数有可能失败,如果失败则返回至是NULL
一旦完成对文件的所有操作后必须使用fclose函数关闭文件
fclose函数需要文件指针作为参数
函数调用结束后必须把文件指针恢复成空指针
文件操作分为两种
1、 把内存中一组连续存储区的内容拷贝到文件里。(写文件)
2、 把文件中一组连续存储区的内容拷贝到内存里。(读文件)
fread函数采用二进制方式对文件进行读操作
fwrite函数用来采用二进制方式对文件进行写操作
这两个函数都需要四个参数
1、 内存中第一个存储区的地址
2、 单个存储区的大小
3、 希望操作的存储区个数
4、 文件指针
函数返回值表示实际操作的存储区个数
例:写入a.bin
1#include<stdio.h>
2int main(){
3 intarr[]={1,2,3,4,5},size=0;
4 FILE*p_file=fopen("a.bin","wb");
5 if(p_file){
6 size=fwrite(arr,sizeof(int),5,p_file);
7 printf("一共写入%d个整数类型存储区",size);
8 fclose(p_file);
9 p_file=NULL;
10 }
11 return 0;
12 }
读出a.bin
1#include<stdio.h>
2int main(){
3 int arr[5]={0},size=0,num=0;
4 FILE*p_file=fopen("a.bin","rb");
5 if(p_file){
6 size=fread(arr,sizeof(int),5,p_file);
7 printf("一共得到%d个整数类型存储区\n",size);
8 for(num=0;num<=4;num++){
9 printf("%d",arr[num]);
10 }
11 fclose(p_file);
12 p_file=NULL;
13 }
14 }
练习:初始化一个二维数组,写程序将其放入一个文件里,
再写一个程序,将文本内容显示成
11111 55555
22222 44444
33333 33333
44444 22222
55555 11111
1#include<stdio.h>
2int main(){
3 int size=0;
4 intarr[5][5]={1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5};
5 FILE*p_file=fopen("a.bin","wb");
6 if(p_file){
7 size=fwrite(arr,sizeof(int),25,p_file);
8 printf("一共写入%d个整数类型存储区\n",size);
9 fclose(p_file);
10 p_file=NULL;
11 }
12 return 0;
13 }
1#include<stdio.h>
2int main(){
3 int size=0,num=0,num1=0;
4 int arr[5][5]={0};
5 FILE *p_file=fopen("a.bin","rb");
6 if(p_file){
7 for(num=4;num>=0;num--){
8 fread(arr[num],sizeof(int),5,p_file);//将文件内容读到存储区
9 }
10 for(num=0;num<=4;num++){
11 for(num1=0;num1<=4;num1++){
12 printf("%d",arr[num][num1]);
13 }
14 printf("\n");
15 }
16 fclose(p_file);
17 p_file=NULL;
18 }
19 return 0;
20 }
复习: 将数组里的数字写入字符串
3 int arr[]={1,2,3,4,5},num=0;
4 char buf[10]={0};
7 for(num=0;num<=4;num++){
8 sprintf(buf , "%d", arr[num]);
10 }
11 printf(“%s”,buf);
将字符串记录到文本文件里
1 #include<stdio.h>
2 #include<string.h>
3 int main(){
4 int arr[]={1,2,3,4,5},num=0;
5 char buf[10]={0};
6 FILE*p_file=fopen("a.txt","wb");
7 if(p_file){
8 for(num=0;num<=4;num++){
9 sprintf(buf,"%d",arr[num]);
10 fwrite(buf,sizeof(char),strlen(buf),p_file);
11 }
12 fclose(p_file);
13 p_file=NULL;
14 }
15 return 0;
16 }
fprintf函数用来把数据按照格式记录到文本文件里,这个函数的参数就是在printf函数参数前面增加一个文件指针
把数据放进文本文档里
1 #include<stdio.h>
2 #include<string.h>
3 int main(){
4 int arr[]={1,2,3,4,5},num=0;
5 char buf[10]={0};
6 FILE*p_file=fopen("a.txt","w");
7 //fprintf函数是以文本形式操作的,不能带b
8 if(p_file){
9 for(num=0;num<=4;num++){
10 /* sprintf(buf,"%d",arr[num]);
11 fwrite(buf,sizeof(char),strlen(buf),p_file);
12 printf("%d",arr[num]);
13 */
14 fprintf(p_file,"%d",arr[num]);
15 }
16 fclose(p_file);
17 p_file=NULL;
18 }
19 return 0;
20 }
fscanf函数可以按照格式从文本文件里获得数据并记录到存储区里
这个函数就是在scanf函数参数前面增加一个文件指针
将数据从文本文档里读出来
1 #include<stdio.h>
2 int main(){
3 int arr[5]={0},num=0;
4 FILE*p_file=fopen("a.txt","r");
5
6 if(p_file){
7 for(num=0;num<=4;num++){
8 //scanf("%d",arr[num]);
9 fscanf(p_file,"%d ",arr+num); // arr+num是地址,不能用arr[num],数值
10 }
11 for(num=0;num<=4;num++){
12 printf("%d",arr[num]);
13 }
14 fclose(p_file);
15 p_file=NULL;
16 }
17 return 0;
18 }
练习:1、编写程序从键盘得到多个人员信息,并把它们记录到二进制文件里,
每个人员信息包含整数类型的id,浮点类型的salary和姓名,文件内容可以追加
编写程序从文件里得到所有人员信息然后显示出来。
写入数据:
1#include<stdio.h>
2#define SIZE 4
3typedef struct{
4 int id;
5 float salary;
6 char name[10];
7}person;
8int main(){
9 person prn={0};
10 int choice=0;
11 FILE *p_file=fopen("person.bin","ab");
12 if(p_file){
13 while(1){
14 printf("请输入ID:");
15 scanf("%d",&(prn.id));
16 printf("请输入工资:");
17 scanf("%g",&(prn.salary));
18 //输入工资后输入姓名,姓名是字符串,因为输入工资后是回车,回车是字符,会自动填充到字符串中,所以要清除缓存区
19 scanf("%*[^\n]");
20 scanf("%*c");
21 printf("请输入姓名:");
22 fgets(prn.name,10,stdin);
23 fwrite(&prn,sizeof(prn),1,p_file);
24 printf("是否需要输入下一个人员信息?0表示不需要,1表示需要\n");
25 scanf("%d",&choice);
26 if(choice==0){
27 break;
28 }
29 }
30 fclose(p_file);
31 p_file=NULL;
32 }
33 return 0;
34 }
输入两个人员信息后 占40个字节,因为4+4+10=18,补到20,再乘2
-rw-rw-r-- 1 tarenatarena 40 8月 17 15:34 person.bin
读数据:
1#include<stdio.h>
2typedef struct{
3 int id;
4 float salary;
5 char name[10];
6}person;
7int main(){
8 int size=0;
9 person prn={0};
10 FILE *p_file=fopen("person.bin","rb");
11 if(p_file){
12 while(1){
13 size=fread(&prn,sizeof(prn),1,p_file);
14 if(size==0){
15 break;
16 }
17 printf("ID是%d\n",prn.id);
18 printf("工资是%g\n",prn.salary);
19 printf("姓名是%s\n",prn.name);
20 }
21 fclose(p_file);
22 p_file=NULL;
23 }
24 return 0;
25 }
计算机里为每个文件保留一个整数,这个整数用来记录下一次读写的开始位置,这个位置一定在相邻两个字节之间
这个整数就是文件头到这个位置之间包含的字节个数,这个整数叫做文件的位置指针
每当从文件中得到n个字节或者向文件中写入n个字节后,位置指针的数值都会自动加n
ftell函数可以获得位置指针的数值
例: 先建立a.txt文档,写入abcdefghijklmn
1#include<stdio.h>
2int main(){
3 char ch=0;
4 FILE*p_file=fopen("a.txt","rb");
5 if(p_file){
6 fread(&ch,sizeof(char),1,p_file);
7 printf("%c\n",ch);
8 fread(&ch,sizeof(char),1,p_file);
9 printf("%c\n",ch);
10 fread(&ch,sizeof(char),1,p_file);
11 printf("%c\n",ch);
12 fclose(p_file);
13 p_file=NULL;
14 }
15 return 0;
16 }
输出 abc
1#include<stdio.h>
2int main(){
3 char ch=0;
4 FILE*p_file=fopen("a.txt","rb");
5 if(p_file){
6 printf("%ld\n",ftell(p_file));
7 fread(&ch,sizeof(char),1,p_file);
8 printf("%c\n",ch);
9 printf("%ld\n",ftell(p_file));
10 fread(&ch,sizeof(char),1,p_file);
11 printf("%c\n",ch);
12 printf("%ld\n",ftell(p_file));
13 fread(&ch,sizeof(char),1,p_file);
14 printf("%c\n",ch);
15 fclose(p_file);
16 p_file=NULL;
17 }
18 return 0;
19 }
0a1b2c
rewind函数把位置指针的数值设置成0
1#include<stdio.h>
2int main(){
3 char ch=0;
4 FILE*p_file=fopen("a.txt","rb");
5 if(p_file){
6 rewind(p_file);
7 printf("%ld\n",ftell(p_file));
8 fread(&ch,sizeof(char),1,p_file);
9 printf("%c\n",ch);
10 rewind(p_file);
11 printf("%ld\n",ftell(p_file));
12 fread(&ch,sizeof(char),1,p_file);
13 printf("%c\n",ch);
14 rewind(p_file);
15 printf("%ld\n",ftell(p_file));
16 fread(&ch,sizeof(char),1,p_file);
17 printf("%c\n",ch);
18 fclose(p_file);
19 p_file=NULL;
20 }
21 return 0;
22 }
执行结果: 0a0a0a
fseek函数文件偏移函数可以把位置指针移动到文件中任何位置
fseek函数中需要指定一个基准位置以及目标到基准位置的距离
SEEK_SET 0 把文件头作为基准位置
SEEK_CUR 1 把当前位置指针作为基准位置
SEEK_END 2 把文件尾作为基准位置
如果目标位置在基准位置后面,距离用正数表示
如果目标位置在基准位置前面,距离用负数表示
距离的数值就是这两个位置之间包含的字节个数
1#include<stdio.h>
2int main(){
3 char ch=0;
4 FILE *p_file=fopen("a.txt","rb");
5 if(p_file){
6 fseek(p_file,2,SEEK_SET);
7 fread(&ch,sizeof(char),1,p_file);
8 printf("%c\n",ch);
9 fseek(p_file,4,SEEK_CUR);
10 fread(&ch,sizeof(char),1,p_file);
11 printf("%c\n",ch);
12 fseek(p_file,-3,SEEK_END);
13 fread(&ch,sizeof(char),1,p_file);
14 printf("%c\n",ch);
15 fclose(p_file);
16 p_file=NULL;
17 }
18 return 0;
19 }
执行结果: c h m
编写程序从person.bin文件中把所有人员ID读出来并显示在屏幕上
只能读出人员ID,不能读出其他信息
1#include<stdio.h>
2typedef struct{
3 int id;
4 float salary;
5 char name[10];
6}person;
7int main(){
8 int id=0,size=0;
9 FILE*p_file=fopen("person.bin","rb");
10 if(p_file){
11 while(1){
12 size=fread(&id,sizeof(int),1,p_file);
13 if(size==0){
14 break;
15 }
16 printf("id是%d\n",id);
17 fseek(p_file,sizeof(person)-sizeof(int),SEEK_CUR);
18 }
19 fclose(p_file);
20 p_file=NULL;
21 }
22 return 0;
23 }