目录
1 标准I/O – 按对象读写
2 标准I/O – 小结
3 标准I/O – 思考和练习
文本文件和二进制的区别:
存储的格式不同:文本文件只能存储文本。除了文本都是二进制文件。
补充计算机内码概念:文本符号在计算机内部的编码(计算机内部只能存储数字0101001....,所以所有符号都要编码)
1 标准I/O – 按对象读写
下列函数用来从流中读写若干个对象:
#include <stdio.h>size_t fread(void *ptr, size_t size, size_t n, FILE *fp);
//void *ptr 读取内容放的位置指针
//size_t size 读取的块大小
//size_t n 读取的个数
//FILE *fp 读取的文件指针size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);
//void *ptr 写文件的内容的位置指针
//size_t size 写的块大小
//size_t n 写的个数
//FILE *fp 要写的文件指针
- 成功返回读写的对象个数;出错时返回EOF
- 既可以读写文本文件,也可以读写数据文件
- 效率高
标准I/O – fread/fwrite – 示例
int s[10];if (fread(s, sizeof(int), 10, fp) < 0) {perror(“fread”);return -1;}struct student {int no;char name[8];float score;} s[] = {{ 1, “zhang”, 97}, {2, “wang”, 95}};fwrite(s, sizeof(struct student), 2, fp);
fread示例
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[]){FILE *fp;char *buff; size_t ret;fp=fopen("1.txt","r");if(fp==NULL){perror("fopen");return 0;}buff=(char*)malloc(100);if(buff==NULL){return 0;}ret = fread(buff,10,1,fp);if(ret==-1){perror("fread");goto end;}printf("buf=%s\n",buff); end:free(buff);fclose(fp);}//运行结果
buf=hello worl
fwrite和fread读写二进制示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct student{char name[16];int age;char sex[8];
};int main(int argc,char *argv[]){FILE *fp;size_t ret;struct student stu;struct student stu2;fp=fopen("1.bin","w");if(fp==NULL){perror("fopen");return 0;}strcpy(stu.name,"zhangsan");stu.age = 49;strcpy(stu.sex,"male");ret = fwrite(&stu,sizeof(stu),1,fp);if(ret ==-1){perror("fwrite");goto end;}else{printf("write struct student success!\n");}fclose(fp); //fp不关闭指针在最后,读取会乱,一定要重新打开。fp=fopen("1.bin","r");if(fp==NULL){perror("fopen");return 0;}ret = fread(&stu2,sizeof(stu),1,fp);if(ret ==-1){perror("fread");goto end;}printf("name=%s,age=%d,sex=%s\n",stu2.name,stu2.age,stu2.sex);end:fclose(fp);}
vim只能查看文本文件,查看二进制文件会显示乱码
注意事项:
文件写完后,文件指针指向文件末尾,如果这时候读,读不出来内容。
解决办法:移动指针(后面讲解)到文件头;关闭文件,重新打开
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct student{char name[16];int age;char sex[8];
};int main(int argc,char *argv[]){FILE *fp;size_t ret;struct student stu2;fp=fopen("1.bin","r");if(fp==NULL){perror("fopen");return 0;}ret = fread(&stu2,sizeof(stu2),1,fp);if(ret ==-1){perror("fread");goto end;}printf("name=%s,age=%d,sex=%s\n",stu2.name,stu2.age,stu2.sex);end:fclose(fp);}
2 标准I/O – 小结
fgetc / fputc
fgets / fputs
fread / fwrite
3 标准I/O – 思考和练习
如何利用fread / fwrite实现文件的复制?
通过命令行参数传递源文件和目标文件名
通过fread返回值判断是否读到文件末尾
#include <stdio.h>#define BUFFER_SIZE 4096int main() {FILE *sourceFile, *targetFile;char buffer[BUFFER_SIZE];size_t bytesRead;// 打开源文件sourceFile = fopen("source.txt", "rb");if (sourceFile == NULL) {printf("无法打开源文件。\n");return 1;}// 打开目标文件targetFile = fopen("target.txt", "wb");if (targetFile == NULL) {printf("无法创建目标文件。\n");fclose(sourceFile);return 1;}// 复制文件内容while ((bytesRead = fread(buffer, 1, BUFFER_SIZE, sourceFile)) > 0) {fwrite(buffer, 1, bytesRead, targetFile);}// 关闭文件fclose(sourceFile);fclose(targetFile);printf("文件复制完成。\n");return 0;
}
使用标准IO写2个学生的结构体数据到文件
#include <stdio.h>
#include <string.h>typedef struct _student
{char name[16];int age;char sex[8];
}student;int main() {FILE *fp;student stu[2];student temp[2];size_t ret;strcpy(stu[0].name,"zhangsan");stu[0].age = 10;strcpy(stu[0].sex,"male");strcpy(stu[1].name,"lisi");stu[1].age = 11;strcpy(stu[1].sex,"female");fp = fopen("1.bin","w");if (fp == NULL) {perror("fopen");return 1;}ret = fwrite(stu,sizeof(student),2,fp);if(ret == -1){perror("fwrite");goto end;}else{printf("Write success\n");}fclose(fp);fp = fopen("1.bin","r");if (fp == NULL) {perror("fopen");return 1;}ret = fread(temp, sizeof(student), 2, fp);if(ret == -1){perror("fread");goto end;}printf("name=%s,age=%d,sex=%s\n",temp[0].name, temp[0].age, temp[0].sex);printf("name=%s,age=%d,sex=%s\n",temp[1].name, temp[1].age, temp[1].sex);
end:fclose(fp);return 0;
}