C语言----文件(高阶篇二十八)
文件指针
定义:
FILE *指针变量名;
如:
FILE *fp1,*fp2;
一次定义了两个指向文件的指针
文件操作方式
※文本方式
文本方式将数据以ASCII码方式存储在文件中,我们电脑中的“文本文件”就是典型的以文本方式存储的文件。
※二进制方式
音乐、图形这类非文本数据,就比较适合使用二进制方式存储
打开文件
格式:
FILE *fopen(文件名,文件使用方式);
如:
FILE *fp;
fp=fopen(“file_a”,”r”);
使用方式列表:
※ ”r”,文本只读
※ ”rb”,二进制只读
※ ”w”,文本只写
※ ”wb”,二进制只写
※ ”a”,文本添加
※ ”ab”,二进制添加
※ r+,w+,a+,rb+,wb+,ab+
带加号方式打开的文件,读写都允许,其它操作与前面6项一样。
打开文件经常会出现错误,比如这个文件根本就不存在。可用以下方法检查:
if((fp=fopen(“file_a”,”r”))= =NULL)
{
printf(“Cannot open this file\n”);
exit(0); /*使程序退出运行*/
}
关闭文件
格式:
fclose(文件指针);
文本文件的读写
写入:
putc(字符,文件指针);
读取:
char getc(文件指针);
判断是否文件尾部:
EOF
因为ASCII字符没有负数,所以在C语言中将EOF定义为-1。用文件读取函数时,遇见-1或EOF即为文件结束标志。
程序1
将字符串”Hello”写入文本文件
// 28-1将字符串hello写入文本文件.c #include <stdio.h> main() { FILE *fp; //定义文件指针 char str[20] = "hello"; //定义写入的字符串 char *pc = str; //指向字符名指针 fp = fopen("myfile.txt", "a"); //打开文件 if (fp == NULL) //如果是 fp为空 { printf("打开文件错误!\n"); exit(0); //系统退出 } while (*pc != '\0') { putc(*pc, fp); //写入字符到文件 pc++; } fclose(fp); //关闭文件 }
程序2
读取程序1中文本文件的内容
// 28-2读取myfile中文本文件的内容.c #include <stdio.h> main() { FILE *fp; //定义文件指针 char str[20]; //定义一个字符,接收文件中的字符 char *pc = str; //指针指向字符名 fp = fopen("myfile.txt", "r"); //读取myfile文件 if (fp == NULL) { printf("打开文件失败!"); exit(0); } //循环读取文件中的字符,直到读取到 EOF结束 *pc = getc(fp); //这一句是为了下面while循环的时候判断是否是EOF while (*pc != EOF) { pc++; *pc = getc(fp); } *pc = '\0'; //赋值结尾符 fclose(fp); printf("%s\n", str); }
除这两个函数外,还有几个可以批量读取数据的函数:
fscanf(文件指针,格式控制字符串,输出表列);
如:
fscanf(fp,”%d %d”,&a,&b);
fprintf(文件指针, 格式控制字符串,输出表列);
如:
fprintf(fp,”%d %d”,a,b);
fgets(数组名,字符个数,文件指针);
如:
fgets(str,n,fp);
fputs(数组名,文件指针);
如:
fputs(str,fp);
※这几个函数有点类似我们平时操作字符串时候用到的函数,只是fgets加了个“字符个数”参数。
二进制文件的读写
二进制文件可以存储任何类型的数据,就有可能出现负数,因此在判断文件尾部时得改用其它方法。
判断文件尾部函数:
int feof(文件指针);
遇到文件结束,返回值为1,否则为0。
写入:
fwrite(内存首地址,内存大小,内存个数,文件指针);
读取:
fread(内存首地址,内存大小,内存个数,文件指针);
程序3
读写二进制文件
// 28-3读写二进制文件.c #include <stdio.h> #include <string.h> //定义学生结构 struct student { char name[10]; //名字 int age; //年龄 }; main() { FILE *fp; struct student stu1, stu2; //定义两个学生结构变量 stu1.age = 17; //学生1年龄赋值 strcpy(stu1.name, "张三瘤子"); //字符串赋值需要用函数赋值 //将结构变量写入文件 fp = fopen("temp.dat", "wb"); //fwrite(内存首地址,内存大小,内存个数,文件指针); fwrite(&stu1, sizeof(struct student), 1, fp); fclose(fp); //读取文件到stu2 fp = fopen("temp.dat", "rb"); //fwrite(内存首地址,内存大小,内存个数,文件指针); fread(&stu2, sizeof(struct student), 1, fp); fclose(fp); printf("%s\n%d\n", stu2.name, stu2.age); }
// 28-4二进制文件与文本文件的区别.c // #include <stdio.h> main() { FILE *fp; int i = 7000; //二进制文件 /* fp = fopen("temp.txt", "wb"); //用二进制打开创建的文件是乱码 fwrite(&i, sizeof(int), 1, fp); */ //文本文件 fp = fopen("temp1.txt", "w"); fprintf(fp,"%d",i); fclose(fp); }
练习
请调用fputs函数,把5个字符串输出到文件中(注意每个字符串用回车分开);再从此文件中读入这5个字符串放在一个字符串数组中;最后把字符串数组中的字符串输出到终端屏幕,以检验所有操作是否正确。
/*28-5 练习.c 请调用fputs函数,把5个字符串输出到文件中(注意每个字符用回车分开); 再从此文件中读入这5个字符串放在一个字符串数组中;最后把字符串数组中的 字符串输出到终端屏幕,以检验所有操作是否正确。 */ #include <stdio.h> main() { char strout[5][10] = { "shout","anything","tent","mouse","ear" }; //写入的文件 char strin[5][10]; FILE *fp; //写入文件 if ((fp = fopen("28.txt", "w")) == NULL) { printf("文件打开错误!"); exit(0); } for (int i = 0; i < 5; i++) { fputs(strout[i],fp); putc('\n',fp); } fclose(fp); //读取文件 if ((fp = fopen("28.txt","r")) == NULL) { printf("文件打开错误!"); exit(0); } for (int i = 0; i < 5; i++) { //fscanf(文件指针, 格式控制字符串, 输出表列); fscanf(fp,"%s",strin[i]); printf("%s\n", strin[i]); } }