思维导图:
使用fread、fwrite完成两个文件的拷贝
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
if(argc !=3)
{
printf("内容输入错误\n");
return -1;
}
//以只读的形式打开文件1
FILE *rfp=NULL;
if((rfp=fopen(argv[1],"r"))==NULL) //外部参数
{
perror("rfp error:");
return -1;
}
//以只写的形式打开文件2
FILE *wfp=NULL;
if((wfp=fopen(argv[2],"w"))==NULL) //外部参数
{
perror("wfp error:");
return -1;
}
//定义搬运工
char buf[128]="";
//来接读取的项数
int num=0;
while(!feof(rfp)&&!ferror(rfp)) //判断文件指针是否到结尾且文件指针没有出错
{
num=fread(buf,1,sizeof(buf),rfp); //读取文件
fwrite(buf,1,sizeof(buf),wfp); //写入数据
}
//关闭文件
fclose(rfp);
fclose(wfp);
return 0;
}
运行效果:
将登录注册框架实现一遍
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//注册功能
int do_register()
{
//1追加形式打开文件
char userName_reg[20]; //账号
char pwd_reg[20]; //密码
//提示输出账号和密码
printf("请输入注册账号:");
fgets(userName_reg,sizeof(userName_reg),stdin); //从终端写入
printf("请输入注册密码:");
fgets(pwd_reg,sizeof(pwd_reg),stdin); //总终端写入
//最后一位为为‘\0’
userName_reg[strlen(userName_reg)-1]='\0';
pwd_reg[strlen(pwd_reg)-1]='\0';
//打开文件
FILE *wfp=NULL;
if((wfp=fopen("usr.txt","a+"))==NULL)
{
perror("wfp error:");
return -1;
}
//将注册账号和密码写入文件,中间空格隔开,每组换行隔开
fprintf(wfp,"%s %s\n",userName_reg,pwd_reg);
//关闭文件
fclose(wfp);
printf("注册成功\n");
return 0;
}
//登录功能
int do_login()
{
//定义容器存放终端输入的内容
char userName_log[20];//账号
char pwd_log[20];//密码
//定义容器存放从文件读取的
char userName[20];//账号
char pwd[20];//密码
//提示输出账号和密码
printf("请输入账户:");
fgets(userName_log,sizeof(userName_log),stdin);
printf("请输入密码:");
fgets(pwd_log,sizeof(pwd_log),stdin);
//最后一位变为‘\0’
userName_log[strlen(userName_log)-1]='\0';
pwd_log[strlen(pwd_log)-1]='\0';
//打开文件比对以读的形式
FILE *rfp=NULL;
if((rfp=fopen("usr.txt","r"))==NULL)
{
perror("rfp error");
return -1;
}
//循环遍历所有文件中的账户和密码
while(1)
{
int res=fscanf(rfp,"%s %s",userName,pwd); //从文件中提取文件
if(res<0)
{
printf("登录失败\n");
//关闭文件
fclose(rfp);
return -1;
}
//判断登录账户和密码是否匹配
if(strcmp(userName_log,userName)==0&& strcmp(pwd_log,pwd)==0)
{
printf("登录成功\n");
//关闭文件
fclose(rfp);
return 0;
}
}
}
int main(int argc, const char *argv[])
{
//定义一个变量存储功能选项
char menu;
//制作菜单
while(1)
{
printf("\t\t=======1注册=======\n");
printf("\t\t=======2登录=======\n");
printf("\t\t=======0退出=======\n");
printf("请输入功能选项:");
scanf("%c",&menu);
while(getchar()!='\n'); //吸收垃圾字符以及回车
//对菜单选项多分支选择
switch(menu)
{
case '1':
{
//执行注册功能
do_register();
}
break;
case '2':
{
//执行登录功能
do_login();
}
break;
case '0':
exit(EXIT_SUCCESS); //退出程序
default:printf("内容是输入错误\n");
}
printf("请输入任意按键回车清屏\n");
while(getchar()!='\n');
system("clear");
}
return 0;
}
运行效果:
完成图像文件信息的读写操作(拷贝)
代码:
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> // 包含 open() 函数的头文件
#include <unistd.h> // 包含 read() 和 write() 函数的头文件
int main(int argc,const char *argv[])
{
FILE *fd_src=NULL;
//以只读的形式打开图片
if((fd_src=fopen("ye.bmp","r"))==NULL)
{
perror("open src:");
return -1;
}
// 创建新的图片文件
FILE *fd_dest=NULL;
if((fd_dest = fopen("dest.bmp", "w"))==NULL)
{
perror("open dest:");
fclose(fd_src); // 关闭原始图片文件
return -1;
}
// 读取原始图片内容,并写入新的图片文件中
char buf[1024];
int num = 0;//读取数据的个数
while(!feof(fd_src)&&!ferror(fd_src)) //判断文件指针是否到结尾且文件指针没有出错
{
num=fread(buf,1,sizeof(buf),fd_src); //读取文件
fwrite(buf,1,sizeof(buf),fd_dest); //写入数据
}
// 关闭两个文件
fclose(fd_src);
fclose(fd_dest);
return 0;
}
运行效果:
面试
标准IO与文件IO的区别
标准IO指使用库函数实现,将内核提供的IO函数接口进行了再次封装,以提高效率
文件IO指使用系统调用,内核提供的函数,每次进行IO操作,进程都会从用户空间向内核空间进行一次切换
区别:标准IO = 文件IO + 缓冲区
什么事IO?
I代表input,输入
O代表output,输出
计算机与外部进行交互的过程称为IO操作
什么是文件指针?
文件指针指的是指向文件地址的一个指针,来自与系统封装好的结构体,可以通过这个结构体来描述整个文件的信息,可以通过fopen打开文件得到文件指针。也存在三个特殊的文件指针分别是:
Stdin:标准输入流指针
Stdout:标准输出流指针
Stderr:标准错误流指针
简述一下系统调用
依赖:文件描述符
依赖库:内核提供的函数
操作过程:每次进行系统调用程序都会从用户空间向内核空间进行一次切换,效率低。
如何判断一个单向链表有环?
首先遍历整个单向链表,判断某个节点是否被多次访问,如果是的那就是有个环。