IO作业2.0

发布时间:2024年01月02日

思维导图

1> 使用fread、fwrite完成两个文件的拷贝

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	if(argc != 3)  	//判断外部参数	
	{
		printf("The terminal format is incorrect\n");
		return -1;
	}
	//定义文件指针
	FILE * fp = NULL;
	FILE * fq = NULL;
	//以只读的形式打开文件
	if((fp = fopen(argv[1],"r")) == NULL)
	{
		perror("fopen error");
		return -1;
	}
	//以只写的形式打开文件
	if((fq = fopen(argv[2],"w")) == NULL)
	{
		perror("fopen error");
		return -1;
	}
	char buf[100]; 	//定义一个文件搬运工
	while(1)
	{
		fread(buf, sizeof(buf), 1, fp);
   		fwrite(buf, sizeof(buf), 1, fq);
		if(feof(fp))
		{
			printf("读取到文件结尾\n");
			break;
		}
		if(ferror(fp))
		{
			printf("读取失败\n");
			break;
		}
	}
	//关闭文件
	fclose(fp);
	fclose(fq);

	printf("拷贝成功\n");
	return 0;
} 

2> 将注册登录框架重新实现一遍

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int do_register() //定义注册函数
{
	//1、以追加的形式打开文件
	FILE * wfp = NULL;
	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';
	
	//以读写追加打开文件 
	if((wfp = fopen("./sts.txt","a+")) == NULL)
	{
		perror("fopen error");
		return -1;
	}

	//2、将注册账号和注册密码写入到文件中,
	//中间用空格隔开,每组用换行隔开
	fprintf(wfp, "%s %s\n", userName_reg, pwd_reg);
	//3、关闭文件
	fclose(wfp);

	printf("注册成功\n");
	return 0;
}
int do_login() //自定义登录功能
{
	//定义容器存放登录账号和登录密码
	char userName_log[20];
	char pwd_reg_log[20];

	//定义变量存储文件读取的账号和密码
	char userName[20];
	char pwd[20];

	//提示输入登录账号和密码
	printf("请输入登录账号");
	fgets(userName_log, sizeof(userName_log), stdin);
	printf("请输入登录密码");
	fgets(pwd_reg_log, sizeof(pwd_reg_log), stdin);

	//将两个字符串中的换行改成'\0'
	userName_log[strlen(userName_log)-1] = '\0';
	pwd_reg_log[strlen(pwd_reg_log)-1] = '\0';

	//打开文件,进行账号和密码的比对
	FILE * rfp = NULL;
	if((rfp = fopen("./sts.txt","r")) == NULL)
	{
		perror("fopen 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_reg_log, pwd)== 0)
		{
			printf("登录成功\n");
			//关闭文件
			fclose(rfp);
			return 0;
		}
	}
}

int main(int argc, const char *argv[])
{
	//定义一个变量存储功能选项
	char num;
	//制作菜单框架
	while(1) 		//重复使用菜单框架
	{
		printf("\t\t====1、注册====\n");
		printf("\t\t====2、登录====\n");
		printf("\t\t====0、退出====\n");
		
		printf("请输入功能选项:");
		scanf("%c",&num);
		while(getchar() != '\n'); 	//循环吸收垃圾字符以及回车,清空缓存区
		//对菜单选项多分支选择
		switch(num){
			case '1':{
					 //执行注册功能
					do_register();
				}
				break;
			case '2':{
					//执行登录功能
					do_login();
				}
				break;
			case '0':
				exit(EXIT_SUCCESS); 		//退出程序

			default:printf("您输入的功能有误请重新输入!!!\n");		
		}

		//输入任意键清屏
		printf("请按任意键输入回车清屏!!!");
		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("./无标题.bmp", "r+")) == NULL)
    {
        perror("fopen error");
        return -1;
    }

    //向后偏移两个字节得到文件的大小
    fseek(fp, 2, SEEK_SET);
	//用于计算图片大小
    unsigned int size;
	//从文件中读取一个整形数据
    fread(&size, sizeof(size), 1, fp);   
	printf("size = %d\n", size);

    //想要更改像素
    unsigned char color[3] = {123, 10, 150};   
    //将光标偏移到图像数据处
    fseek(fp, 54, SEEK_SET);
    
    for(int i=0; i<1473; i++)  //外层   
	{
        for(int j=0; j<648; j++)   //内列
        {
            fwrite(color, sizeof(color), 1, fp);
        }
    }

    //关闭文件
    fclose(fp);

    return 0;
}

标准IO和文件IO的区别:

标准IO=文件IO+缓冲区

标准IO依赖于库函数,该函数包含了一个缓冲区,该函数会将数据统一放入缓冲区,等待缓冲物时间刷新后,进行一并调用到内核,效率较高

文件IO属于内核提供的函数,依赖于系统调用,每进行一次系统调用,程序都会从用户空间向内核进行一次调换,效率偏低

什么是IO:

程序对外部设备完成信息交换的过程

什么是文件指针:

指向文件地址的指针,该类型是在stdio.h中定义了一个用于描述文件所有信息的结构体

作用:用于描述文件信息,是文件的操作句柄

内涵:包含了缓冲区和文件描述符

简述系统调用:

属于内核,依赖的句柄有文件描述符

每进行一次系统调用,程序都会从用户空间向内核进行一次调换,效率偏低

如何判断一个单向链表有环:

在遍历结果时,若是有一个节点地址被多次访问,则证明有环

文章来源:https://blog.csdn.net/mmj12/article/details/135348055
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。