用RIO包或者标准IO包实现文件的复制,包括直接复制,unix2dos和dos2unix三种形式,命令行含3个参数,一个长参数 --direct,–unix2dos,–dos2unix指明复制方式,后面两个参数依次是源文件名和目标文件名,要求使用getopt_long函数
解题思路:
unix和dos的主要区别是换行符的不同,一个是\r\n一个是\n,要手动实现unix2dos和dos2unix,只需考虑最后的换行符,我使用的RIO包,基本结构是逐行读逐行写,然后在写的时候不写换行符,然后自己手动补上去就可以了。
注意getopt_long函数的使用,由于这里没有短选项,所以调用一次getopt_long函数后optind指针会自动指向参数表,所以不需要再调用这个函数,只需要strcpy一下optind指向的agrv表就可以了
测试结果
代码
#include<stdio.h>
#include<getopt.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include"csapp.h"
static struct option opts[]= //option lists
{
{"direct",0,NULL,0},
{"dos2unix",0,NULL,1},
{"unix2dos",0,NULL,2}
};
int main(int argc,char* agrv[])
{
int way,opt;
int n;
char src[50];
char dst[50];
char* Dos = "\r\n"; // dos endline
char* Unix ="\n"; // unix endline
char buf[MAXLINE];
opt=getopt_long(argc,agrv,"",opts,NULL);
strcpy(src,agrv[optind]); //optind points to agrv[2]
strcpy(dst,agrv[optind+1]); // strcpy agrv[3]
int srcfile = open(src,O_RDONLY,0);
if(srcfile==-1)
{
printf("open error\n");
return 0;
}
int dstfile = open(dst,O_WRONLY|O_CREAT|O_TRUNC,DEF_MODE);
rio_t rio;
Rio_readinitb(&rio,srcfile);
if(opt==0) //copy directly
{
while((n=Rio_readlineb(&rio,buf,MAXLINE))!=0)
{
Rio_writen(dstfile,buf,n);
}
}
else if (opt==1) //dos2unix
{
while((n=Rio_readlineb(&rio,buf,MAXLINE))!=0)
{
if(n>2)
{
Rio_writen(dstfile,buf,n-2);
Rio_writen(dstfile,Unix,1);
}
else
{
Rio_writen(dstfile,Unix,1);
}
}
}
else if(opt==2) //unix2dos
{
while((n=Rio_readlineb(&rio,buf,MAXLINE))!=0)
{
if(n>1)
{
Rio_writen(dstfile,buf,n-1);
Rio_writen(dstfile,Dos,2);
}
else
{
Rio_writen(dstfile,Dos,2);
}
}
}
else
{
Rio_writen(STDERR_FILENO,"error",5);
}
close(srcfile);
close(dstfile);
return 0;
}