Unix/DOS换行 符转换的程序,学习一下C对文件的处理

在Linux下的换行是/n,而在 Windows下的换行是/r/n。不经过处理的话,两者的文件在显示的时候会出现问题,比如一个Linux的文本文件用Windows记事本打开的时候不会换行格式很乱,一个Windows文件在Linux下用VI打开的话会出现^M字符等。下面这个程序是作者给出用于处理/r/n和/r的转换的问题,其中使用了C语言的标准IO库中的文件操作函数,主要的注释我已经给出,大家可以学习一下: 01.#include 03.#include 07.void usage()       //打印使用 方法的函数 09.{ 11.printf("/n  Usage/t/t ctxfm -u|-U|-d|-D infile outfile/n/n"); 13.printf("  -u -U/tturn a dos text into unix form./n"); 15.printf("  -d -D/tturn a dos text into unix form./n/n"); 17.exit(0); 19.} 23./* 本函数将DOS格式转换 成UNIX格式 */ 25.void turnunix(char *infile,char *outfile) 27.{ 28.     FILE *in,*out; 30.char ch,flag=0; 33.     if((in=fopen(infile,"rb"))==NULL) {               //"rb",以二进制读方式打开输入的文件,为了防止/r/n在Windows下被转换成/n 34.                                                                  //在Linux下不用考虑 35.             printf("Cannot open file %s/n",infile); 37.        exit(0); 39.        } 42.     if((out=fopen(outfile,"rb"))!=NULL) {          //判断输出的文件是否已经存在,如果存在则报错退出 43.             fclose(out); 45.        printf("ERROR! Outfile %s has been existened!",outfile); 46.             exit(0); 47.     } 48.    if((out=fopen(outfile,"wb"))==NULL) {             //创建输出文件,"wb"以写方式创建二进制文件 49.             printf("Cannot open outfile %s/n",outfile); 50.             exit(0); 52.        } 54.     while(1)                                       {   /* 循环开始,从infile逐个字符复制到outfile */ 56.        ch=fgetc(in);             // 从infile读一个字符,不过这里有点问题,以二进制方式打开文件似乎用fread处理输入比较标准,这里                                           //仅仅读一个字符的话用fgetc也可以 58.        if(feof(in))break;        // 判断是否到文件结尾 60.         /* 以下几行的注释: 如果当前字符为/r,则flag=1,然后将/r写入outfile,如果下个字符是/n,就说明遇到了DOS的换行符,这里需要使用fseek函数将outfile的写入位置回退一个字符,然后写入/n覆盖之前的/r。如果下个字符不是/n,则前一个/r 61.为普通字符,flag=0,继 续处理其他字符。*/ 62.            if(ch=='/r')flag=1; 63.            else if((ch=='/n')&& flag)fseek(out,-1L,1);   //似乎应该是fseek(out, -1L, SEEK_CUR);比较好 65.                         else flag=0; 67.        fputc(ch,out);           // 将ch写入outfile 69.        } 72.     if(fclose(in)==EOF||fclose(out)==EOF)               /* 关文件 */ 73.            printf("File close error!/n"); 75.        exit(0); 77.        } 79.} 83./* 此函数处理UNIX到DOS 的转换 */ 85.void turndos(char *infile,char *outfile) 87.{ 88.          FILE *in,*out; 90.char ch; 93.          if((in=fopen(infile,"rb"))==NULL){ 94.                  printf("Cannot open file %s/n",infile); 96.        exit(0); 98.        } 100.if((out=fopen(outfile,"rb"))!=NULL) { 101.                  fclose(out); 103.        printf("ERROR! Outfile %s has been existened!",outfile); 105.        exit(0); 106.          } 108.if((out=fopen(outfile,"wb"))==NULL) { 109.                  printf("Cannot open outfile %s/n",outfile); 111.        exit(0); 112.          } 113.          //下面就是凡是遇 到/n的时候,就都向outfile中写/r/n 114.          while(1) { 115.                  ch=fgetc(in); 117.        if(feof(in))break; 119.        if(ch=='/n')                                                                  /* in unix is /n*/ 121.                fputs("/r/n",out); 123.        else fputc(ch,out); 125.        } 126.          if(fclose(in)==EOF||fclose(out)==EOF)          /* 关文件 */ 127.          { 128.                 printf("File close error!/n"); 130.        exit(0); 132.        } 134.} 137.intmain(int argc,char*argv[]) 139.{ 140.          /* check parameters */ 142.if(argc!=4)   usage(); 145.          /*比较简单的参数 处理*/ 147.if(!strcmp(argv[1],"-u")||!strcmp(argv[1],"-U")) 149.        turnunix(argv[2],argv[3]); 150.          else if(!strcmp(argv[1],"-d")||!strcmp(argv[1],"-D")) 152.                 turndos(argv[2],argv[3]); 154.else usage(); 156.          return 0; 158.} 需要注意: 1)作者使用的是"rb"这样的 方式来读写文件,也就是说把文件当成二进制文件来读写,这个可能是和他在Windows下写程序有关。上网找了一下资料,在Windows下用C语言以文本方式读文件的话,Windows会自动把/r/n转换成/n,而用二进制方式则不发生任何转换。在Linux下由于不区分文本而二进制,所以b参数无效。但是考虑到可移植性,作者还是使用了b参数来读写文件。2)fseek函数在二进制模式下 才能正常工作,该函数定义如下:int fseek(FILE* STREAM, long offset, int origin)从origin开始移动offset个字节 长度,origin可以取SEEK_SET,SEEK_CUR和SEEK_END三个值,分别对应文件开始,当前和结束位置

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值