CSAPP:系统I/O作业:手动实现unix2dos和dos2unix

用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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值