IO进程线程复习:IO

标准IO:

1.打开文件

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//定义文件指针
	FILE *fp=NULL;
	//以只读的形式打开文件
	//fp=fopen("./text.txt","r");
	//以只写的形式打开文件
	fp=fopen("./time.c","w");
	if(fp==NULL)
	{
		perror("fopen error");
		return -1;
	}
	printf("文件打开成功\n");

	//关闭文件
	fclose(fp);
	return 0;
}

2.单字符读写

#include<myhead.h>

int main(int argc, const char *argv[])
{
	FILE *fp=NULL;
	//以只写的形式打开文件
	fp=fopen("./test.txt","w");
	if(fp==NULL)
	{
		perror("fopen error");
		return -1;
	}

	//向文件中写入数据
	fputc('W',fp);
	fputc('e',fp);
	fputc('l',fp);
	fputc('c',fp);
	fputc('o',fp);
	fputc('m',fp);
	fputc('e',fp);

	//关闭文件
	fclose(fp);

	//以只读的形式再次打开文件
	fp=fopen("./test.txt","r");
	if(fp==NULL)
	{
		perror("fopen error");
		return -1;
	}
	
	while(1)
	{
		char ch=fgetc(fp);//从fp指向的文件中读取一个字符
		if(ch==EOF)//读取到文件结束了
		{
			break;
		}
		printf("%c ",ch);
	}
	printf("\n");
	//关闭文件
	fclose(fp);
	return 0;
}

3.使用fgetc统计给定文件行数。

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//判断外部传参是否合法
	if(argc!=2)
	{
		printf("input file error\n");
		printf("usage:./a.out filename\n");
	}
	//定义文件指针
	FILE *fp=NULL;
	//以只读的形式打开文件
	fp=fopen(argv[1],"r");
	if(fp==NULL)
	{
		perror("fopen error");
		return -1;
	}
	
	//统计行号
	int line=0;
	char ch=0;//遍历文件的字符
	while(1)
	{
		//循环从文件中读取一个字符,知道读取结束为止
		char ch=fgetc(fp);
		if(ch==EOF)
		{
			break;
		}

		//判断获取的字符是否为‘\n’
		if(ch=='\n')
		{
			line++;
		}
	}
	printf("一共有%d行\n",line);

	//关闭文件
	fclose(fp);

	return 0;
}

4.使用fgetc和fput完成两个文件拷贝。

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//判断外部传参是否合法
	if(argc!=3)
	{
		printf("input file error\n");
		printf("usage:./a.out srcfile destfile\n");
	}
	//定义文件指针
	FILE *srcfp=NULL;
	FILE *destfp=NULL;
	//以只读的形式打开源文件
	srcfp=fopen(argv[1],"r");
	if(srcfp==NULL)
	{
		perror("fopen srcfile error");
		return -1;
	}
	//以只写的形式打开目标文件
	destfp=fopen(argv[2],"w");
	if(destfp==NULL)
	{
		perror("fopen destfile error");
		return -1;
	}
	
	char ch=0;//遍历文件的字符
	while(1)
	{
		//循环从文件中读取一个字符,知道读取结束为止
		char ch=fgetc(srcfp);
		if(ch==EOF)
		{
			break;
		}
		//将读取的数据放入到目标文件中
		fputc(ch,destfp);
	}

	//关闭文件
	fclose(srcfp);
	fclose(destfp);

	return 0;
}

5.字符串读写

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//定义文件指针,以只写的形式打开文件
	FILE *fp=NULL;
	if((fp=fopen("./02test.txt","w"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	//向文件中写入字符串
	fputs("hello\n",fp);
	fputs("world\n",fp);

	//关闭文件
	fclose(fp);

	//以只读的形式再次打开文件
	if((fp=fopen("./02test.txt","r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	char buf[5];//字符串的搬运工
	while(1)
	{
		char *p=fgets(buf,sizeof(buf),fp);//从fp中读取字符串到buf中
		if(p==NULL)
		{
			break;
		}
		printf("buf=%s\n",buf);
	}
	//关闭文件
	fclose(fp);


	return 0;
}

6.格式化读写

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//以只写的形式打开文件
	FILE *fp=NULL;
	if((fp=fopen("./03test.txt","w"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	//定义要写入的数据
	int numb=1000;
	char name[]="zhangzhiren";
	int age=30;
	fprintf(fp,"%d %s %d\n",numb,name,age);

	//关闭文件
	fclose(fp);


	//使用fscanf从终端读取数据
	int value;
	fscanf(stdin,"%d",&value);
	printf("value=%d\n",value);

	return 0;
}

7.新读写函数取代旧读写函数

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//单字符读写操作
	char ch=0;
	ch=fgetc(stdin);//ch=getchar();
	fputc(ch,stdout);//putchar(ch);
	fgetc(stdin);//getchar();
	printf("\n************\n");

	//字符串读写操作
	char str[128]="";
	fgets(str,sizeof(str),stdin);//gets(str);
	fputs(str,stdout);//puts(str);
	printf("\n************\n");

	//格式化读写操作
	int num=0;
	fscanf(stdin,"%d",&num);//scanf("%d",&num);
	fprintf(stdout,"num=%d\n",num);//printf("num=%d\n",num);

	return 0;
}

8.验证缓冲区大小

#include<myhead.h>

int main(int argc, const char *argv[])
{
	printf("%ld\n",stdout->_IO_buf_end - stdout->_IO_buf_base);//1024
	printf("%ld\n",stdout->_IO_buf_end - stdout->_IO_buf_base);//1024

	getchar();//stdin
	printf("%ld\n",stdin->_IO_buf_end - stdin->_IO_buf_base);//1024

	//验证全缓存大小
	FILE *fp=NULL;
	if((fp=fopen("./04test.txt","w"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	fprintf(fp,"hello");
	printf("%ld\n",fp->_IO_buf_end - fp->_IO_buf_base);//4096
	fclose(fp);

	//验证不缓存大小
	perror("result");
	printf("%ld\n",stderr->_IO_buf_end - stderr->_IO_buf_base);//0
	return 0;
}

9.行缓存的刷新时机

#include<myhead.h>

int main(int argc, const char *argv[])
{
	/*
	//1.缓冲区刷新时机未到,不会展示在终端上
	printf("hello world");
	while(1);//阻塞
	*/
/*
	//2.遇到‘\n’会刷新行缓存
	printf("hello world\n");
	while(1);//阻塞
	*/
/*
	//3.文件结束后,会刷新行缓存
	printf("hello world");
	*/
/*
	//4.当关闭文件指针后,会刷新行缓存
	printf("hello world");
	fclose(stdout);//关闭文件指针
	while(1);
*/	
/*
	//5.使用fflush刷新缓冲区后,会刷新行缓存
	printf("hello world");
	fflush(stdout);
	while(1);
	*/
/*
	//6.当输入输出发生切换时,会刷新行缓存
	int num;
	printf("请输入num的值:");
	scanf("%d",&num);
	*/

	//7.当缓冲区满了后,会刷新缓冲区
	for(int i=0;i<1025;i++)
	{
		printf("A");
	}
	while(1);
	
	return 0;
}

10.全缓存的刷新时机

#include<myhead.h>

int main(int argc, const char *argv[])
{
	FILE *fp=NULL;
	if((fp=fopen("./06test.txt","w+"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	/*
	//1.缓冲区刷新时机未到,不会展示在终端上
	fprintf(fp,"hello world");
	while(1);//阻塞
	*/

	//2.遇到‘\n’不会刷新全缓存
	fprintf(fp,"hello world\n");
	while(1);//阻塞
	
/*
	//3.文件结束后,会刷新全缓存
	fprintf(fp,"hello world");
	*/
/*
	//4.当关闭文件指针后,会刷新全缓存
	fprintf(fp,"hello world");
	fclose(fp);//关闭文件指针
	while(1);
*/	
/*
	//5.使用fflush刷新缓冲区后,会刷新全缓存
	fprintf(fp,"hello world");
	fflush(fp);
	while(1);
	*/
/*
	//6.当输入输出发生切换时,会刷新全缓存
	int num;
	fprintf(fp,"请输入num的值:");
	fgetc(fp);
	*/
/*
	//7.当缓冲区满了后,会刷新缓冲区
	for(int i=0;i<4097;i++)
	{
		fprintf(fp,"A");
	}
	while(1);
*/	
	return 0;
}

11.不缓存的刷新时机:只要有数据,直接被刷新

#include<myhead.h>

int main(int argc, const char *argv[])
{
	fprintf(stderr,"A");//向标准出错中写入数据
	while(1);
	return 0;
}

12.获取系统当前时间

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//1.获取时间的秒数
	time_t sysTime=time(NULL);

	//2.通过秒数获取时间结构体指针
	struct tm *t=localtime(&sysTime);

	//3.将时间打印在终端上
	//printf("%4d-%2d-%2d %2d:%2d:%2d\n",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);

	//将时间的格式串存储到一个数组中
	char time_buf[128]="";
	snprintf(time_buf,sizeof(time_buf),"%4d-%2d-%2d %2d:%2d:%2d\n",t->tm_year+1900,t->tm_mon,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
	
	printf("time_buf=%s\n",time_buf);
	return 0;
}

13.使用fgets统计给定文件行数

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//判断外部传参
	if(argc!=2)
	{
		printf("input file error\n");
		printf("usage:./a.out filename\n");
		return -1;
	}
	//定义文件指针,以只读形式打开文件
	FILE *fp=NULL;
	if((fp=fopen(argv[1],"r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	//统计行数
	int line=0;
	char buf[5]="";
	while(1)
	{
		char *p=fgets(buf,sizeof(buf),fp);
		if(p==NULL)
			break;
		//判断最后一个字符为'\n'
		if(buf[strlen(buf)-1]=='\n')
			line++;
	}
	//输出行数
	printf("一共%d行\n",line);

	//关闭文件
	fclose(fp);
	return 0;
}

14.使用fputs和fgets完成两个文件拷贝

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//判断终端输入文件是否合法
	if(argc!=3)
	{
		printf("input file error\n");
		printf("usage:./a.out srcfile destfile\n");
		return -1;
	}
	//定义文件指针,以读的发生打开源文件
	FILE *srcfp=NULL;
	if((srcfp=fopen(argv[1],"r"))==NULL)
	{
		perror("fopen srcfp error");
		return -1;
	}
	//定义文件指针,以写的方式打开文件
	FILE *destfp=NULL;
	if((destfp=fopen(argv[2],"w"))==NULL)
	{
		perror("fopen destfp error");
		return -1;
	}
	char buf[128]="";//定义搬运工
	while(1)
	{
		char *p=fgets(buf,sizeof(buf),srcfp);
		if(p==NULL)
			break;
		fputs(p,destfp);//将读取的文件放入目标文件
	}
	printf("copy success\n");
	//关闭文件
	fclose(srcfp);
	fclose(destfp);
	return 0;
}

15.完成注册登录功能,做个小菜单

功能1:注册功能,输入注册账号和登录密码,将账号和密码写入文件中。

功能2:登录功能,提示并输入登录账户和登录密码,并用其遍历文件中的每一组账户和密码,如果匹配成功,则登录成功,如果全部不匹配,则提示登录失败。

#include<myhead.h>
int do_register();
int do_login();

int main(int argc, const char *argv[])
{
	int menu=0;
	while(1)
	{
		system("clear");//执行终端指令
		printf("\t\t=====老张零食店登录界面=====\n");
		printf("\t\t=====1.注册=====\n");
		printf("\t\t=====2.登录=====\n");
		printf("\t\t=====0.退出=====\n");
		printf("请输入选项:");
		scanf("%d",&menu);
		getchar();

		//对菜单多分支选择
		switch(menu)
		{
			case 1:
				{
					//注册功能
					do_register();
				}
				break;

			case 2:
				{
					//登录功能
					int res=do_login();
					if(res==0)
					{
						printf("登录成功\n");
					}
					else
					{
						printf("登录失败\n");
					}
				}
				break;

			case 0:goto END;

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

		//提示输入任意键按回车结束
		printf("请输入任意键按回车结束!!!\n");
		while(getchar()!='\n');
	}
END:
	return 0;
}

//定义注册函数
int do_register()
{
	//定义注册账号和密码
	char register_name[20]="";
	char register_pwd[20]="";

	printf("请输入注册账号:");
	fgets(register_name,sizeof(register_name),stdin);
	register_name[strlen(register_name)-1]='\0';//将换行换成'\0'
	printf("请输入注册密码:");
	fgets(register_pwd,sizeof(register_pwd),stdin);
	register_pwd[strlen(register_pwd)-1]='\0';
	
	//以追加的形式打开文件
	FILE *fp=NULL;
	if((fp=fopen("user.txt","a"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	//将当前的账号和密码写入文件
	fprintf(fp,"%s %s\n",register_name,register_pwd);

	//关闭文件
	fclose(fp);

	printf("注册成功\n");

	return 0;
}

//定义登录函数
int do_login()
{
	char login_name[20]="";
	char login_pwd[20]="";
	
	printf("请输入登录账号:");
	fgets(login_name,sizeof(login_name),stdin);
	login_name[strlen(login_name)-1]='\0';//将换行换成'\0'
	printf("请输入登录密码:");
	fgets(login_pwd,sizeof(login_pwd),stdin);
	login_pwd[strlen(login_pwd)-1]='\0';

	//打开文件,遍历所有的账号和密码
	FILE *fp=NULL;
	if((fp=fopen("user.txt","r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	//循环读取账号和密码
	char name[20]="";
	char pwd[20]="";
	while(1)
	{
		int res=fscanf(fp,"%s %s",name,pwd);//从文件中读取一组数据
		if(res==EOF)
		{
			fclose(fp);
			return -1;
		}

		//判断账号和密码是否匹配
		if(strcmp(login_name,name)==0 || strcmp(login_pwd,pwd)==0)
		{
			//关闭文件
			fclose(fp);
			return 0;
		}

	}
	
}

16.模块化读写字符串

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//打开文件
	FILE *fp=NULL;
	if((fp=fopen("./08test.txt","w"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	char str[128]="";
	printf("请输入>>>");
	fgets(str,sizeof(str),stdin);//从终端获取一个字符串到str中
	str[strlen(str)-1]='\0';    //将换行换成‘\0’

	//将字符串写入到文件中
	fwrite(str,1,strlen(str),fp);

	//关闭文件
	fclose(fp);

	//重新以只读的形式打开文件
	if((fp=fopen("./08test.txt","r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	char rbuf[128]="";
	int res=fread(rbuf,1,sizeof(rbuf),fp);//从08test.txt中读取一个字符串
	fwrite(rbuf,1,res,stdout);//将读取的字符串输出到终端
	printf("\n");

	//关闭文件
	fclose(fp);	
	return 0;
}

17.模块化读写整数

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//打开文件
	FILE *fp=NULL;
	if((fp=fopen("./09test.txt","w"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	int num=98;//要存入的数据
	//将整型数据写入到文件中
	fwrite(&num,sizeof(int),1,fp);//将整型数据num存入到09test.txt文件中

	//关闭文件
	fclose(fp);

	//重新以只读的形式打开文件
	if((fp=fopen("./09test.txt","r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	int key=0;
	int res=fread(&key,sizeof(key),1,fp);//从09test.txt中读取整数
	printf("key=%d\n",key);

	//关闭文件
	fclose(fp);	
	return 0;
}

18.模块化读写结构体

#include<myhead.h>

//定义结构体类型
struct Stu
{
	int numb;
	char name[20];
	double score;
};

int main(int argc, const char *argv[])
{
	//定义文件指针,以只写的形式打开文件
	FILE *fp=NULL;
	if((fp=fopen("./10test.txt","w"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	//定义一个结构体数组
	struct Stu s[3]={{1001,"张三",90},{1002,"李四",78},{1003,"王五",100}};

	//将结构体数组中的内容全部写入到文件
	fwrite(s,sizeof(struct Stu),3,fp);//将整个结构体数组写入到文件10test.txt

	//关闭文件
	fclose(fp);

	//重新以只读的形式打开文件
	if((fp=fopen("./10test.txt","r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	struct Stu t;
	int res=fread(&t,sizeof(t),1,fp);//从10test.txt文件中读取一个结构体变量
	res=fread(&t,sizeof(t),1,fp);//从10test.txt文件中读取一个结构体变量
	res=fread(&t,sizeof(t),1,fp);//从10test.txt文件中读取一个结构体变量

	printf("t.numb=%d,t.name=%s,t.score=%.2lf\n",t.numb,t.name,t.score);
	
	//关闭文件
	fclose(fp);
	return 0;
}

19.feof、ferror

对于fread而言,当出错时,是不区分文件结束还是错误出现的,需要使用这两个函数加以区分

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//定义文件指针,以只读的形式打开文件
	FILE *fp=NULL;
	if((fp=fopen("./10test.txt","r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	char buf;
	while(1)
	{
		//读取字符
		fread(&buf,1,1,fp);
		//判断当前文件是否到最后
		if(feof(fp))
		{
			printf("文件到末尾\n");
			break;
		}
		//判断读取失败
		if(ferror(fp))
		{
			printf("文件操作失败\n");
			break;
		}
		printf("%c ",buf);
	}
	//关闭文件
	fclose(fp);
	return 0;
}

20.对于光标的操作

#include<myhead.h>

//定义结构体类型
struct Stu
{
	int numb;
	char name[20];
	double score;
};

int main(int argc, const char *argv[])
{
	//定义文件指针,以只写的形式打开文件
	FILE *fp=NULL;
	if((fp=fopen("./11test.txt","w"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	//定义一个结构体数组
	struct Stu s[3]={{1001,"张三",90},{1002,"李四",78},{1003,"王五",100}};

	//将结构体数组中的内容全部写入到文件
	fwrite(s,sizeof(struct Stu),3,fp);//将整个结构体数组写入到文件11test.txt

	//关闭文件
	fclose(fp);

	//重新以只读的形式打开文件
	if((fp=fopen("./11test.txt","r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	struct Stu t;
	//将光标从开始位置向后偏移,定位到李四前面
	//fseek(fp,sizeof(struct Stu),SEEK_SET);
	//将光标从结束位置向前偏移,定位到李四前面
	fseek(fp,-2*sizeof(struct Stu),SEEK_END);
	int res=fread(&t,sizeof(t),1,fp);//从11test.txt文件中读取一个结构体变量

	printf("t.numb=%d,t.name=%s,t.score=%.2lf\n",t.numb,t.name,t.score);
	
	//关闭文件
	fclose(fp);
	return 0;
}

21.使用标准IO完成对BMP图像的操作

#include<myhead.h>

int main(int argc, const char *argv[])
{
	FILE *fp=NULL;
	//以读写的形式打开文件
	if((fp=fopen("./meinv.bmp","r+"))==NULL)
	{
		perror("fopen error");
		return -1;
	}
	//定义变量接收大小
	int bmpSize=0;
	fseek(fp,2,SEEK_SET);

	//读取图像的大小
	fread(&bmpSize,sizeof(int),1,fp);
	printf("bmpSize=%d\n",bmpSize);//输出图像的大小

	//将光标定位在图像像素矩阵位置
	fseek(fp,54,SEEK_SET);

	//准备一个像素值
	unsigned char color[3]={255,0,0};//蓝色
	
	//遍历矩阵
	for(int i=0;i<100;i++)//外行
	{
		for(int j=0;j<640;j++)//内列
		{
			fwrite(color,sizeof(color),1,fp);
		}
	}

	//关闭文件
	fclose(fp);
	return 0;
}

文件IO:

22.文件描述符

#include<myhead.h>

int main(int argc, const char *argv[])
{
	printf("%d\n",stdin->_fileno);//stdin对应的文件描述符 0
	printf("%d\n",stdout->_fileno);//stdout对应的文件描述符 1
	printf("%d\n",stderr->_fileno);//stderr对应的文件描述符 2
	return 0;
}

23.open使用

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//定义文件描述符数量
	int fd=-1;
	if((fd=open("./12test.txt",O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("open error");
		return -1;
	}
	printf("open success fd=%d\n",fd);
	return 0;
}

24.验证O_EXCL,close使用

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//定义文件描述符数量
	int fd=-1;
	if((fd=open("./fengjing.bmp",O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0664))==-1)
	{
		perror("open error");
		return -1;
	}
	printf("open success fd=%d\n",fd);

	//关闭文件
	close(fd);
	return 0;
}

25.读写操作write、read

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//打开文件
	FILE *fp=NULL;
	if((fp=fopen("./08test.txt","w"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	char str[128]="";
	printf("请输入>>>");
	fgets(str,sizeof(str),stdin);//从终端获取一个字符串到str中
	str[strlen(str)-1]='\0';    //将换行换成‘\0’

	//将字符串写入到文件中
	fwrite(str,1,strlen(str),fp);

	//关闭文件
	fclose(fp);

	//重新以只读的形式打开文件
	if((fp=fopen("./08test.txt","r"))==NULL)
	{
		perror("fopen error");
		return -1;
	}

	char rbuf[128]="";
	int res=fread(rbuf,1,sizeof(rbuf),fp);//从08test.txt中读取一个字符串
	fwrite(rbuf,1,res,stdout);//将读取的字符串输出到终端
	printf("\n");

	//关闭文件
	fclose(fp);	
	return 0;
}

26.光标操作lseek

#include<myhead.h>

int main(int argc, const char *argv[])
{
	int fd=-1;
	if((fd=open("./zhuzhuxia.bmp",O_RDONLY))==-1)
	{
		perror("open error");
		return -1;
	}
	//输出图像文件大小
	printf("size=%ld\n",lseek(fd,0,SEEK_END));

	//从文件中获取图像文件大小
	int bmpSize=0;
	lseek(fd,2,SEEK_SET);//将光标偏移到开头后的两个字节后
	
	read(fd,&bmpSize,sizeof(int));//读取四字节数据中的内容
	printf("bmpSize=%d\n",bmpSize);

	//将光标偏移到矩阵部分
	lseek(fd,54,SEEK_SET);

	//准备一个像素值
	unsigned char color[3]={0,255,0};//绿色
	
	//对图像修改
	for(int i=0;i<100;i++)//外行
	{
		for(int j=0;j<640;j++)//内列
		{
			write(fd,color,sizeof(color));
		}
	}

	//关闭文件
	close(fd);
	return 0;
}

27.使用fread和fwrite完成两个文件的拷贝

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//判断终端输入是否合法
	if(argc!=3)
	{
		printf("input file error\n");
		printf("usage:srcfile destfile\n");
		return -1;
	}
	//定义两个文件指针,一个用于读,一个用于写
	FILE *srcfp=NULL;
	FILE *destfp=NULL;
	if((srcfp=fopen(argv[1],"r"))==NULL)
	{
		perror("srcfile fopen error");
		return -1;
	}
	if((destfp=fopen(argv[2],"w"))==NULL)
	{
		perror("destffile fopen error");
		return -1;
	}
	//循环读取搬运工
	while(1)
	{
		char buf[10]={0};
		int res=fread(buf,1,sizeof(buf),srcfp);//循环每次读取字符
		fwrite(buf,1,res,destfp);//循环打印到第二个文件中

		//判断光标是否在结尾
		if(feof(srcfp))
			break;

		//关闭文件
		fclose(srcfp);
		fclose(destfp);
	}

	return 0;
}

28.使用read、write完成两个文件的拷贝

#include<myhead.h>

int main(int argc, const char *argv[])
{
	if(argc!=3)
	{
		printf("input file error\n");
		printf("usage:./a.out srcfile destfile\n");
		return -1;
	}
	int srcfd=-1;
	int destfd=-1;
	if((srcfd=open(argv[1],O_RDONLY))==-1)
	{
		perror("open srcfd error");
		return -1;
	}
	if((destfd=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("open srcfd error");
		return -1;
	}

	char buf[1024]="";
	while(1)
	{
		memset(buf,0,sizeof(buf));
		int res=read(srcfd,buf,sizeof(buf));
		write(destfd,buf,res);
		if(res==0)
			break;
		
	}
	close(srcfd);
	close(destfd);
	return 0;
}

29 将时间在文件中跑起来

#include<myhead.h>
//定义获取行号的函数
int get_line(int fd)
{
	char buf;//读取字符串
	int line=0;
	while(read(fd,&buf,1)>0)
	{
		if(buf=='\n')
		{
			line++;
		}
	}
	return line;
}
int main(int argc, const char *argv[])
{
	//定义时间变量
	time_t sysTime,oldtime;

	//定义时间结构体指针变量
	struct tm *t;

	//定义文件描述符变量
	int fd=-1;

	//以追加的形式打开文件
	if((fd=open("./02time.txt",O_RDWR|O_CREAT|O_APPEND,0664))==-1)
	{
		perror("open error");
		return -1;
	}

	//获取当前文件行号
	int line=get_line(fd);

	char timebuf[128]="";//存放时间的格式串

	while(1)
	{
		//获取时间
		sysTime=time(NULL);
		t=localtime(&sysTime);

		if(oldtime!=sysTime)
		{
			//将数组清空
			bzero(timebuf,sizeof(timebuf));

			//将oldtime重新赋值
			oldtime=sysTime;
			//将时间转换为格式串
			snprintf(timebuf,sizeof(timebuf),"%d、%2d:%2d:%2d\n",line++,t->tm_hour,t->tm_min,t->tm_sec);

			//写入文件中
			write(fd,timebuf,strlen(timebuf));
		}
	}
	//关闭文件
	close(fd);
	return 0;
}

30.使用fread和fwrite实现图片拷贝

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//定义文件指针
	FILE *srcfp=NULL;
	FILE *destfp=NULL;
	//以只读的形式打开源文件,以只写的形式打开目标文件
	if((srcfp=fopen("./meinv2.bmp","r"))==NULL)
	{
		perror("srcfp fopen error");
		return -1;
	}
	if((destfp=fopen("./meinv.bmp","w"))==NULL)
	{
		perror("destfp fopen error");
		return -1;
	}
	char buf[1024];
	int res=0;
	while((res=fread(buf,1,sizeof(buf),srcfp))!=0)
	{
		fwrite(buf,1,res,destfp);
	}

	//关闭文件
	fclose(srcfp);
	fclose(destfp);

	return 0;
}

31.文件描述符变量的拷贝没有产生新的文件描述符,两个变量中存储的是同一个文件描述符,共享同一光标。

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//以读写的形式打开文件
	int fd1=-1;
	if((fd1=open("./16test.txt",O_RDWR|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("fd1 open error");
		return -1;
	}

	//向文件中写入数据
	char wbuf[]="hello world";
	write(fd1,wbuf,sizeof(wbuf));//写入文件

	//将光标定位在开头
	lseek(fd1,0,SEEK_SET);

	//定义一个新的文件描述符
	int fd2=fd1;

	//将fd2的光标后移
	lseek(fd2,6,SEEK_SET);

	//使用fd1从文件中读取数据
	char rbuf[128]="";
	read(fd1,rbuf,sizeof(rbuf));
	printf("rbuf=%s\n",rbuf);//如果结果为hello world,说明拷贝后不共享光标;
							//如果结果为world,说明拷贝后,共享光标
	//关闭文件
	close(fd1);
	return 0;
}

32.使用dup函数完成文件描述符的拷贝

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//以读写的形式打开文件
	int fd1=-1;
	if((fd1=open("./16test.txt",O_RDWR|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("fd1 open error");
		return -1;
	}

	//向文件中写入数据
	char wbuf[]="hello world";
	write(fd1,wbuf,sizeof(wbuf));//写入文件

	//将光标定位在开头
	lseek(fd1,0,SEEK_SET);

	//拷贝旧的文件描述符,得到一个新的文件描述符
	int fd2=dup(fd1);
	printf("fd1=%d,fd2=%d\n",fd1,fd2);//3   4

	//将fd2的光标后移
	lseek(fd2,6,SEEK_SET);

	//使用fd1从文件中读取数据
	char rbuf[128]="";
	read(fd1,rbuf,sizeof(rbuf));
	printf("rbuf=%s\n",rbuf);//如果结果为hello world,说明拷贝后不共享光标;
							//如果结果为world,说明拷贝后,共享光标
	//关闭文件
	close(fd1);
	return 0;
}

33.使用dup2完成两个文件描述符的拷贝

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//以读写的形式打开文件
	int fd1=-1;
	if((fd1=open("./16test.txt",O_RDWR|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("fd1 open error");
		return -1;
	}

	//再打开一个文件
	int fd2=-1;
	if((fd2=open("./13test.txt",O_RDONLY))==-1)
	{
		perror("fd2 open error");
		return -1;
	}
	//向文件中写入数据
	char wbuf[]="hello world";
	write(fd1,wbuf,sizeof(wbuf));//写入文件

	//将光标定位在开头
	lseek(fd1,0,SEEK_SET);

	//拷贝旧的文件描述符,得到一个新的文件描述符
	dup2(fd1,fd2);
	printf("fd1=%d,fd2=%d\n",fd1,fd2);//3   4

	//将fd2的光标后移
	lseek(fd2,6,SEEK_SET);

	//使用fd1从文件中读取数据
	char rbuf[128]="";
	read(fd1,rbuf,sizeof(rbuf));
	printf("rbuf=%s\n",rbuf);//如果结果为hello world,说明拷贝后不共享光标;
							//如果结果为world,说明拷贝后,共享光标
	//关闭文件
	close(fd1);
	return 0;
}

34.多次使用open函数打开同一个文件,操作文件时,光标不共享

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//以读写的形式打开文件
	int fd1=-1;
	if((fd1=open("./16test.txt",O_RDWR|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("fd1 open error");
		return -1;
	}

	//再打开一个文件
	int fd2=-1;
	if((fd2=open("./16test.txt",O_RDWR|O_CREAT|O_TRUNC,0664))==-1)
	{
		perror("fd2 open error");
		return -1;
	}
	//向文件中写入数据
	char wbuf[]="hello world";
	write(fd1,wbuf,sizeof(wbuf));//写入文件

	//将光标定位在开头
	lseek(fd1,0,SEEK_SET);

	//将fd2的光标后移
	lseek(fd2,6,SEEK_SET);

	//使用fd1从文件中读取数据
	char rbuf[128]="";
	read(fd1,rbuf,sizeof(rbuf));
	printf("rbuf=%s\n",rbuf);//如果结果为hello world,说明拷贝后不共享光标;
							//如果结果为world,说明拷贝后,共享光标
	//关闭文件
	close(fd1);
	return 0;
}

35.文件状态stat

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//判断外部传参个数
	if(argc!=2)
	{
		write(2,"input file error\n",strlen("input file error\n"));
		fwrite("usage:./a.out filename\n",1,strlen("usage:./a.out filename"),stderr);
		return -1;
	}

	//定义文件状态结构体变量
	struct stat st;
	if(stat(argv[1],&st)==-1)
	{
		perror("stat error");
		return -1;
	}

	//输出当前文件信息
	switch(st.st_mode&S_IFMT)
	{
		case S_IFSOCK:
			printf("套接字文件\n");
			break;
		case S_IFLNK:
			printf("链接文件\n");
			break;
		case S_IFREG:
			printf("普通文件\n");
			break;
		case S_IFBLK:
			printf("块设备文件\n");
			break;
		case S_IFDIR:
			printf("目录文件\n");
			break;
		case S_IFCHR:
			printf("字符设备文件\n");
			break;
		case S_IFIFO:
			printf("管道文件\n");
			break;
	}
	printf("mode:%#o\t size=%ld\t inode=%ld\n",st.st_mode&07777,st.st_size,st.st_ino);
	return 0;
}

36.对目录的操作:opendir、readdir、closedir

#include<myhead.h>

int main(int argc, const char *argv[])
{
	//打开目录
	DIR *dp=NULL;
	if((dp=opendir("."))==NULL)
	{
		perror("opendir error");
		return -1;
	}

	//读取目录中的信息
	struct dirent *dirp=NULL;
	while((dirp=readdir(dp))!=NULL)
	{
		switch(dirp->d_type)
		{
			case DT_BLK:
				printf("块设备文件\n");
				break;
			case DT_DIR:
				printf("目录文件\n");
				break;
			case DT_REG:
				printf("普通文件\n");
				break;
		}
		printf("inode:%ld\t size:%d\t name=%s\n",dirp->d_ino,dirp->d_reclen,dirp->d_name);
	}
	//关闭目录
	closedir(dp);
	return 0;
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值