情景导入: 浏览网友博客时,发现一段程序,想在自己电脑运行一下。直接复制粘贴过来代码中每行前都有行号,手动删除几个后,发现该程序有200多行。脑中一个念头,“我是程序员啊,平常老是说工作自动化,为什么我自己的事还不能自动化呢?”。于是,我决定写一个程序去快速(1s内)删除它。补充说明,我当时是在windows行环境。
这个程序的逻辑很简单,就是每次遇到回车时,读后面的字符,判断是数字,则用空格替换。直到读到文件末尾。当然这里有一个小细节,也是是windows和linux的不同,windows用换行符和回车符表示下一行,而linux则是只用回车表示下一行。原因在于linux终端驱动可以自动做一些转换。客官不信,有图为证(windows下用二进制软件打开一个txt文件):
当时,我用读写的方式打开要转换的文件,一边读一边写。结果并没有想象中好啊。同样,我将相同代码用gcc编译,然后运行。结果如下:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #define oops(msg) { perror(msg);exit(0);} int main( int argc , char *argv[] ) { int r ; char ch ; FILE *fp_rw; if ( argc < 2 ) { exit(0); } fp_rw = fopen(argv[1],"rt+"); //打开要截掉行号的文件 if ( NULL == fp_rw ) { oops("error"); } while( isspace(ch = fgetc(fp_rw)) ); //跳过空格 if ( ch == EOF ) { exit(0); } fseek(fp_rw,-1L,SEEK_CUR); //回退一个字符 while( isdigit(ch = fgetc(fp_rw) )) { fseek(fp_rw,-1L,SEEK_CUR); r = fputc(' ' , fp_rw); if ( r < 0 ) oops("error"); } while((ch = fgetc(fp_rw)) != EOF ) { if ( '\n' == ch ) { while( isspace(ch = fgetc(fp_rw)) ); if ( EOF == ch ) { return 0; } fseek(fp_rw,-1L,SEEK_CUR); while( isdigit(ch = fgetc(fp_rw) )) { fseek(fp_rw,-1L,SEEK_CUR); if ( EOF == ch ) { return 0 ; } printf("c"); r = fputc(' ' , fp_rw); if ( r < 0 ) oops("error"); } } } fclose(fp_rw); printf("success!\n"); return 0; } |
原因猜测,是windows的c库实现出现问题。
今天发现这个功能还是有点用的,所以写了个 windows版本,虽然简单,但是对我还是有帮助的。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #define oops(msg) { perror(msg);exit(0);} int main( int argc , char *argv[] ) { char ch ; FILE *fp_r,*fp_w; if ( argc < 3 ) { exit(0); } //打开文件 fp_r = fopen(argv[1],"rt"); fp_w = fopen(argv[2],"w"); if ( NULL == fp_r || NULL == fp_w ) { oops("error"); } while( isspace(ch = fgetc(fp_r)) ); if ( ch == EOF ) { exit(0); } while( isdigit(ch = fgetc(fp_r) )) ; if ( EOF == ch ) { exit(0); } fputc(ch,fp_w); while((ch = fgetc(fp_r)) != EOF ) { if ( '\n' == ch ) { while( isspace(ch = fgetc(fp_r)) ); if ( EOF == ch ) { fclose(fp_r); fclose(fp_w); return 0; } while( isdigit(ch = fgetc(fp_r) )) ; if ( EOF == ch ) { fclose(fp_r); fclose(fp_w); } //输进回车 fputc('\n',fp_w); } fputc(ch,fp_w); } fclose(fp_w); fclose(fp_r); printf("success!\n"); return 0; } |