在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三个值,分别对应文件开始,当前和结束位置
Unix/DOS换行 符转换的程序,学习一下C对文件的处理
最新推荐文章于 2022-02-23 15:02:25 发布