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

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

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

     代码:

   

main.c
1 #include <stdio.h>
2
3  #define MAXLINE 10
4
5  int getLine(char s[], int lim);
6  void copy(char to[], char from[]);
7 int calcLen(char s[]);
8
9 int main()
10 {
11
12 int len, index, row;
13 char line[MAXLINE];
14 char post_line[MAXLINE][MAXLINE];
15
16 row = 0;
17 while((len = getLine(line, MAXLINE)) > 0)
18 {
19 if(line[len-1] == '\n') //判断读入的一行字符串的倒数第二个字符是否为'\n'
20 index = len - 2;
21 else
22 index = len - 1;
23 while(line[index] == ' ' || line[index] == '\t') //消除字符串结尾处的' '和'\t'
24 {
25 line[index] = line[index+1];
26 line[index+1] = line[index+2];
27 --index;
28 }
29 if(index > -1)
30 copy(post_line[row++], line); //如果line是全空格字符串,对其进行消除字符串结尾处
31 //操作使得line成为一个空字符串,故不将其(空字符串)
32 //拷贝到post_line中。
33 }
34
35 for(index = 0; index < row; ++index) //post_line针对其中每个字符串的倒数第二个字符是否为'\n'
36 //在打印的时候做不同处理。
37 if(post_line[index][calcLen(post_line[index])-1] != '\n')
38 printf("%s\n", post_line[index]);
39 else
40 printf("%s",post_line[index]);
41
42 return 0;
43 }
44
45 int getLine(char s[], int lim)
46 {
47 int i;
48 char c;
49
50 for(i = 0; i < lim-1 && (c = getchar()) != EOF && c != '\n'; ++i)
51 s[i] = c;
52 if(c == '\n')
53 {
54 s[i] = c;
55 ++i;
56 }
57 s[i] = '\0';
58 fflush(stdin);
59
60 return i;
61 }
62
63 void copy(char to[], char from[])
64 {
65 int i;
66
67 i = 0;
68 while((to[i] = from[i]) != '\0') //超过字符数组的容量,截断。
69 ++i;
70 //if(i == MAXLINE-1)
71 //to[i] = '\0';
72 //fflush(stdin); //每输入一行字符后(键入'\n'之后),清空输入缓冲区。
73 }
74
75 int calcLen(char s[])
76 {
77 int i;
78
79 i = 0;
80 while(s[i] != '\0')
81 ++i;
82
83 return i;
84 }

     分析:

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

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

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

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

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

     参考代码:

  

main.c
1 #include <stdio.h>
2
3 #define MAXLINE 1000
4
5 int getLine(char line[], int maxline);
6 int remove(char s[]);
7
8 int main()
9 {
10
11 char line[MAXLINE];
12
13 while(getLine(line, MAXLINE) > 0)
14 if(remove(line) > 0)
15 printf("%s", line);
16
17 return 0;
18 }
19
20 int remove(char s[]) //删除字符串s末尾的空格和制表符并返回它的新长度
21 {
22 int i;
23
24 i = 0;
25 while(s[i] != '\n') //查找'\n'在s数组中对应的下标
26 ++i;
27 --i;
28 while(i >= 0 && (s[i] == '' || s[i] == '\t')) //从字符串末尾起向前查找字符值不是' '和'\t'的字符
29 //所对应的下标
30 --i;
31 if(i >= 0)
32 {
33 ++i;
34 s[i] = '\n';
35 ++i;
36 s[i] = '\0';
37 }
38
39 return i;
40 }

     分析:

     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'; 

                                       }   

posted on 2011-04-21 04:35  将军之盾  阅读(1402)  评论(0编辑  收藏  举报