嵌入式学习-IO进程线程-Day2
一、思维导图
二、面试题
1.标准IO与文件IO的区别
标准IO依赖于库函数,是程序提供的函数。使用该函数时需要先将要操作的数据放入缓存区,等待缓存区刷新时机到了之后,调用系统调用函数将数据一起刷入内核空
文件IO依赖于系统调用,是内核提供的函数。进行该调用,都会执行一次系统调用,效率较低。
标准IO = 文件IO + 缓冲区
2.什么是IO
i指input o指output
IO就是指程序对外部设备进行信息交换的过程
3.什么是文件指针?
指向文件地址的一个指针,头文件是stdio.h,是结构体类型,用于描述整个文件啊信息,是文件操作的句柄。
包含了一个缓冲区,和一个用于系统调用的文件描述符。
4.简述系统调用
系统调用是通过文件描述符使用内核提供的函数对系统进行调用,并从用户空间向内核空间进行一次切换,效率较低
5.如何判断一个单向链表中有环
遍历链表,如果一个节点的访问次数大于1,则有环
三、作业
1.使用fread、fwrite完成两个文件的拷贝
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
//定义两个文件指针
FILE *srcfp=NULL,*dstfp=NULL;
//打开文件
if((srcfp=fopen("./1.txt","r"))==NULL)
{
perror("fopen error");
return -1;
}
if((dstfp=fopen("./2.txt","w"))==NULL)
{
perror("fopen error");
return -1;
}
char rbuf[10]="";
//拷贝字符串
while(1)
{
if(feof(srcfp)!=0)
break;
int res=fread(rbuf,1,sizeof(rbuf),srcfp);
fwrite(rbuf,1,res,dstfp); //保证每次写入的个数都是读取的个数
memset(rbuf,0,sizeof(rbuf));//对rbuf清零
}
printf("拷贝成功\n");
//关闭文件
fclose(srcfp);
fclose(dstfp);
return 0;
}
运行结果
2.将注册登录框架重新实现一遍
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int do_register();
int do_login();
int main(int argc, const char *argv[])
{
//定义变量存储功能选项
int menu;
while(1)
{ //菜单框架
printf("\t\t=====1.注册=====\n");
printf("\t\t=====2.登录=====\n");
printf("\t\t=====0.退出=====\n");
printf("输入功能选项:");
scanf("%d",&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;
}
int do_register()
{
//定义
FILE *wfp=NULL;
char usrName_reg[20]="";
char pwd_reg[20]="";
//输入帐号和密码
printf("输入注册帐号:");
fgets(usrName_reg,sizeof(usrName_reg),stdin);
printf("输入注册密码:");
fgets(pwd_reg,sizeof(pwd_reg),stdin);
//将字符串最后一位换行改成'\0'
usrName_reg[strlen(usrName_reg)-1]='\0';
pwd_reg[strlen(pwd_reg)-1]='\0';
//以追加写的方式打开文件
if((wfp=fopen("usr.txt","a"))==NULL)
{
perror("fopen error");
return -1;
}
//写入
fprintf(wfp,"%s %s\n",usrName_reg,pwd_reg);
printf("写入成功\n");
//关闭文件
fclose(wfp);
return 0;
}
int do_login()
{
//定义容器存放登录帐号和密码
char usrName_log[20]="";
char pwd_log[20]="";
//定义变量存储文件读取的帐号和密码
char usrName[20]="";
char pwd[20]="";
//提示输入帐号和密码
printf("输入登录帐号:");
fgets(usrName_log,sizeof(usrName_log),stdin);
printf("输入登录密码:");
fgets(pwd_log,sizeof(pwd_log),stdin);
//将输入的账号和密码最后一位换成\0
usrName_log[strlen(usrName_log)-1]='\0';
pwd_log[strlen(pwd_log)-1]='\0';
//打开文件
FILE *rfp=NULL;
if((rfp=fopen("./usr.txt","r"))==NULL)
{
perror("fopen error");
return -1;
}
//循环遍历所有账户,进行比对
while(1)
{
int res=fscanf(rfp,"%s %s",usrName,pwd);
if(res<0)
{
printf("登陆失败 未注册\n");
fclose(rfp);
return 1;
}
if(strcmp(usrName_log,usrName)==0)
{
if(strcmp(pwd_log,pwd)==0)
{
printf("登录成功\n");
fclose(rfp);
return 0;
}
else
{
printf("密码错误\n");
fclose(rfp);
return 1;
}
}
}
}
运行结果
3.完成图像文件信息的读写操作
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
//打开文件
FILE *fp=NULL;
if((fp=fopen("./tupian.bmp","r+"))==NULL)
{
perror("fopen error");
return -1;
}
//输出图像的大小信息
fseek(fp,2,SEEK_SET);//3-6字节表示图像大小
int size;
fread(&size,sizeof(size),1,fp);
printf("size=%d\n",size);
fseek(fp,0,SEEK_END); //光标移动到最后,也可以输出文件大小
fread(&size,sizeof(size),1,fp);
printf("size=%d\n",size);
//文件信息所占字节15-54
//更改图片部分像素
fseek(fp,54,SEEK_SET);//55-58是图片数据
unsigned char color[3]={0,255,0};
for(int i=300;i<356;i++) //行
{
for(int j=0;j<534;j++) //列
{
fwrite(color,sizeof(color),1,fp);
}
}
//关闭文件
fclose(fp);
return 0;
}
运行结果