目录
1 标准I/O – 按对象读写
2 标准I/O – 小结
3 标准I/O – 思考和练习
文本文件和二进制的区别:
存储的格式不同:文本文件只能存储文本。除了文本都是二进制文件。
补充计算机内码概念:文本符号在计算机内部的编码(计算机内部只能存储数字0101001....,所以所有符号都要编码)
下列函数用来从流中读写若干个对象:
#include
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 要写的文件指针
标准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
#include
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
#include
#include
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
#include
#include
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);
}
fgetc / fputc
fgets / fputs
fread / fwrite
如何利用fread / fwrite实现文件的复制?
通过命令行参数传递源文件和目标文件名
通过fread返回值判断是否读到文件末尾
#include
#define BUFFER_SIZE 4096
int 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
#include
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;
}