删除每个输入行末尾的空格,制表符,并删除全空格行

     源自《The C Programming Language》P22 pr1-18:

 

     编写一个程序,删除每个输入行末尾的空格,制表符,并删除完全是空格的行

 

     代码:

 

     #include #define MAXLINE 10 int getLine(char s[], int lim); void copy(char to[], char from[]); int calcLen(char s[]); int main() { int len, index, row; char line[MAXLINE]; char post_line[MAXLINE][MAXLINE]; row = 0; while((len = getLine(line, MAXLINE)) > 0) { if(line[len-1] == '/n') //判断读入的一行字符串的倒数第二个字符是否为'/n' index = len - 2; else index = len - 1; while(line[index] == ' ' || line[index] == '/t') //消除字符串结尾的' '和'/t' { line[index] = line[index+1]; line[index+1] = line[index+2]; --index; } if(index > -1) copy(post_line[row++], line); //如果line是全空格字符串,对其进行消除字符串结尾 // 处操作使得line成为一个空字符串,故不将其(空字 //符串)拷贝到post_line中。 } for(index = 0; index < row; ++index) //post_line针对其中每个字符串的倒数第二个 //字符是否为'/n'在打印的时候做不同处理。 if(post_line[index][calcLen(post_line[index])-1] != '/n') printf("%s/n", post_line[index]); else printf("%s",post_line[index]); return 0; } int getLine(char s[], int lim) { int i; char c; for(i = 0; i < lim-1 && (c = getchar()) != EOF && c != '/n'; ++i) s[i] = c; if(c == '/n') { s[i] = c; ++i; } s[i] = '/0'; fflush(stdin); //每输入一行字符后(键入'/n'之后),清空输入缓冲区。 return i; } void copy(char to[], char from[]) { int i; i = 0; while((to[i] = from[i]) != '/0') ++i; if(i == MAXLINE-1) to[i] = '/0'; } int calcLen(char s[]) { int i; i = 0; while(s[i] != '/0') ++i; return i; }

 

 

     分析:

 

     1,   针对输入的字符串(line)的倒数第二个字符是否为'/n',分情况进行消除字符串末尾的空格及制表符处理。

 

     2,   针对处理后的字符串(post_line[n])的倒数第二个字符是否为'/n',在打印的时候分情况进行处理。

 

     3,   getLine函数:读入一行字符后,将输入缓冲区清空,这样当超过字符数组line的界限的字符会被清除掉,

                                如果不清空,则在下次调用getLine函数时,上次超出的字符部分会被getchar函数直接

                                读到这次的line字符数组中,造成混乱。

 

     参考代码:

 

     #include #define MAXLINE 1000 int getLine(char line[], int maxline); int remove(char s[]); int main() { char line[MAXLINE]; while(getLine(line, MAXLINE) > 0) if(remove(line) > 0) printf("%s", line); return 0; } int remove(char s[]) //删除字符串s末尾的空格和制表符并返回它的新长度 { int i; i = 0; while(s[i] != '/n') //查找'/n'在s数组中对应的下标 ++i; --i; while(i >= 0 && (s[i] == '' || s[i] == '/t')) //从字符串末尾起向前查找字 //符是' '和'/t'的字符所对应的下标 --i; if(i >= 0) { ++i; s[i] = '/n'; ++i; s[i] = '/0'; } return i; }

 

 

     分析:

 

     1,  对比于自己实现的代码,发现这段代码简洁多了,思路也很清晰和易懂。

 

     2,  有点缺憾之处:(a),每次输入一行字符,处理结果会紧接着下一行输出,不太容易观看,

                               而上面那段代码就不存在这个问题。

                               (b),参考代码没有考虑一行字符串没有'/n'的情况,这和它将MAXLINE设成1000有关,

                                      极端的情况是一个字符串就是1000个字符,并且倒数第二字符不是'/n',如果MAXLINE

                                      的值比较小的话,这个问题就凸现出来了,相比于此,上段代码考虑了这种情况。

                                      修改remove函数:

                                      while(s[i] != '/n' && i < MAXLINE - 2)

                                                ++i;

                                      if(i != MAXLINE - 2)

                                                 --i;

                                      while(i >= 0 && (s[i] == ' ' || s[i] == '/t'))

                                                 --i;

                                       if( i >= 0 && i < MAXLINE - 2)

                                       {

                                                 ++i;

                                                 s[i] = '/n';

                                                 ++i;

                                                 s[i] = '/0'; 

                                       }   

 

 

 

 

 

你可能感兴趣的:(C)