带命令参数的detab函数
源自《The C Programming Language》P102 pr5-11:
修改程序entab和detab(第一章练习中编写的函数),使它们接受一组作为参数的制表符停止位。如果启动程序时不带参数,
则使用默认的制表符停止位设置。
代码:
#include <stdio.h> #include <stdlib.h> #define TABINC 8 int main(int argc, char* argv[]) { int c; int pos; int nb; int tab_inc; pos = 1; nb = 0; if(argc == 1) tab_inc = TABINC; else tab_inc = atoi(*++argv); while((c = getchar()) != EOF) if(c == '\t') { nb = tab_inc - (pos - 1) % tab_inc; while(nb > 0) { putchar(' '); ++pos; --nb; } } else if(c == '\n') { putchar(c); pos = 1; } else { putchar(c); ++pos; } return 0; }
参考代码:
#include <stdio.h> #define MAXLINE 100 //一行字符串的最大长度 #define TABINC 8 //默认地制表符停止位 #define YES 1 //标记是否遇到制表符停止位 #define NO 0 void settab(int argc, char** argv, char* tab); void detab(char* tab); int tabpos(int pos, char* tab); int main(int argc, char* argv[]) { char tab[MAXLINE+1]; //标识一行字符串中哪些位是制表符停止位, //数组tab中的每一个元素对应这文本行的一个位置(tab[0]不用) settab(argc, argv, tab); detab(tab); return 0; } #include <stdlib.h> /*settab:设置一行字符中哪些位是停止位,哪些位不是*/ void settab(int argc, char* argv[], char* tab) { int i; int pos; //程序在当前文本行的位置 if(argc <= 1) for(i = 1; i <= MAXLINE; ++i) if(i % TABINC == 0) //每隔8个字符设置一个停止位(即tab[i%TABINC] = YES) tab[i] = YES; else tab[i] = NO; else { for(i = 1; i <= MAXLINE; ++i) tab[i] = NO; while(--argc > 0) { pos = atoi(*++argv); if(pos > 0 && pos <= MAXLINE) tab[pos] = YES; } } } /*detab:将'\t'用相应的空格代替(综合argv中的参数)*/ void detab(char* tab) { int c; int pos; pos = 1; while((c = getchar()) != EOF) if(c == '\t') //当c='\t'时,在遇到下一个停止位前,用空格填充之 do putchar(' '); while(tabpos(pos++, tab) != YES); else if(c == '\n') { putchar(c); pos = 1; } else { putchar(c); ++pos; } } /*tabpos:判读某个位置是否是一个制表符停止位*/ int tabpos(int pos, char* tab) { if(pos > MAXLINE) //如果pos大于MAXLINE,则返回YES,表示终止 return YES; else return tab[pos]; }
分析:
1,函数分析:
数组tab:tab中的没一个元素对应着文本行的一个位置,即,tab[1]对应着文本行的第一个位置(pos = 1),
如果文本行的某个位置处有一个制表符停止位,与之对应的tab[i]元素取值YES,否则取值NO。
函数settab:对制表符停止位进行初始化。如果没有输入参数(argc = 1),则默认地将文本行上每隔TABINC
个位置设置一个制表符停止位;如果有输入参数,则根据输入参数来设置制表符停止位。
函数tabpos:判断某个位置是否是一个制表符停止位,如果pos的取值大于MAXLINE,则返回YES;
否则,返回tab[pos]。
2,代码对比分析:
对比代码和参考代码,参考代码最大优化之处:能同时设置若干个位置为制表符停止位,而代码中只能设置一个
通用的制表符停止位(即每个n个字符设置一个制表符停止位)。