思维导图
1、使用fread、fwrite:完成两个文件的拷贝
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
int main(int argc, const char *argv[])
{
//判断输入是否合法
if(argc>3)
{
printf("输入不合法\n");
return -1;
}
//定义两个文件指针,一个用于读,一个用于写
FILE *fp1=NULL;
FILE *fp2=NULL;
if((fp1=fopen(argv[1],"r"))==NULL)
{
perror("");
return -1;
}
if((fp2=fopen(argv[2],"w"))==NULL)
{
perror("");
return -1;
}
//循环读取搬运
while(1)
{
char buf[10];//定义搬运工
int res=fread(buf,1,sizeof(buf),fp1);//循环每次读取字符
fwrite(buf,1,res,fp2);//循环打印到第二个文件中
if(feof(fp1))//执行玩上述操作后进行判断光标是否在结尾
{
break;//光标到结尾后退出循环
}
}
//文件关闭
fclose(fp1);
fclose(fp2);
return 0;
}
2、将注册登录框架重新实现一遍
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
int reg()
{
//定义两个容器用于存放注册的用户名和用户密码
char usrname[20];
char passwd[20];
FILE *fp=NULL;
if((fp=fopen("user.txt","a"))==NULL)
{
perror("");
return -1;
}
//输入注册的用户名何用户摩玛并存入到容器中
printf("请输入注册用户名");
scanf("%s",usrname);
printf("请输入注册密码");
scanf("%s",passwd);
//使用fgets需要吸收掉输入的垃圾字符使用scanf无需吸收垃圾字符
//usrname[strlen(usrname)-1]='\0';
//passwd[strlen(passwd)-1]='\0';
//打印到文件中去
fprintf(fp,"%s %s\n",usrname,passwd);
printf("注册成功\n");
fclose(fp);
}
int login()
{
//定义两个容器存放已有用户名和密码
char usrexist[20];
char pasexist[20];
//定义两个容器用于存放登录的用户名和用户密码
char usrname[20];
char passwd[20];
//定义文件指针用于比对
FILE *fp=NULL;
if((fp=fopen("user.txt","r"))==NULL)
{
perror("");
return -1;
}
printf("请输入登录用户名");
scanf("%s",usrname);
printf("请输入登录密码");
scanf("%s",passwd);
while(1)//循环进行比对
{
fscanf(fp,"%s %s",usrexist,pasexist);//循环输入已有用户
if(strcmp(usrname,usrexist)==0&&strcmp(passwd,pasexist)==0)//判断登录账号密码是否已经保存
{
printf("登录成功\n");
break;
}
if(feof(fp))
{
printf("未找到该账户,登录失败\n");
break;
}
}
fclose(fp);
}
int main(int argc, const char *argv[])
{
while(1)
{
//界面绘制
int a;//定义变量记录操作
printf("====================1.注册====================\n");
printf("====================2.登录====================\n");
printf("====================0.退出====================\n");
printf("请输入你要执行的操作");
scanf("%d",&a);
while(getchar()!='\n');//吸收垃圾字符
switch(a)//分支判断是何操作
{
case 1:
{
reg();//注册
break;
}
case 2:
{
login();//登录
break;
}
case 0:
{
exit(EXIT_SUCCESS);
}
default:
{
printf("输入有误\n");
}
}
printf("输入任意键清屏\n");
getchar();
while(getchar()!='\n');//吸收垃圾字符
system("clear");
}
return 0;
}
3、完成图像文件信息的读写操作(将一张全黑图的一半转换成蓝色)
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
int main(int argc, const char *argv[])
{
//定义文件指针指向图片
FILE *fp=NULL;
if((fp=fopen("./1.bmp","r+"))==NULL)
{
perror("");
return -1;
}
//计算图片大小
//偏移两个字节用于跳过图片类型描述符
fseek(fp,2,SEEK_SET);
unsigned int size;
fread(&size,sizeof(size),1,fp);//通过读取后四个字节计算文件大小
printf("文件大小为%d\n",size);
fseek(fp,54,SEEK_SET);
unsigned char color[3]={180,100,50};
for(int i=0;i<198;i++)
{
for(int j=0;j<356;j++)
{
fwrite(color,sizeof(color),1,fp);
}
}
fclose(fp);
return 0;
}
面试题
1、文件IO与标准IO的区别
1、文件IO依赖于系统提供的函数,而标准IO依赖于库函数
2、文件IO每次调用函数都要从用户空间转换到内核空间,而标准IO不需要,所以文件IO的效率要低于标准IO
3、文件IO不需要经过缓冲区,而标准IO会经过缓冲区,总的来说就是:标准IO=文件IO+缓冲区
2、什么是IO
IO就是输入和输出,是实现文件与文件之间信息转换的过程。
3、什么是文件指针
文件指针本质上就是一个指针,他指向文件类型的数据,所以叫文件指针。他来源于标准IO库函数,是标准IO库函数操作文件的接口。在定义后可以作为函数的参数进而操作文件。实际上包含了一个缓冲区和一个用于系统调用的文件描述符。
4、简述一下系统调用
系统调用就是文件IO。指的是不适用标准IO库直接使用内核提供的函数进行操作。每次在系统调用时都会从用户空间转换到内核空间,效率相对较低
5、如何判断一个单向链表中有环
在循环遍历整个单向链表时,如果其中一个节点地址被多次访问,则有环。