删除每个行末尾的空格及制表符 ,并删除完全是空格的行

练习1-18:编写一个程序,删除每个行末尾的空格及制表符 ,并删除完全是空格的行

#include <stdio.h>
#include <stdlib.h>
 
#define MAXQUEUE 1001
 
int advance(int pointer)
{
  if (pointer < MAXQUEUE - 1)
    return pointer + 1;
  else
    return 0;
}
 
int main(void)
{
  char blank[MAXQUEUE];
  int head, tail;
  int nonspace;
  int retval;
  int c;
 
  retval = nonspace = head = tail = 0;
  while ((c = getchar()) != EOF) {
    if (c == '\n') {
      head = tail = 0;
      if (nonspace)
        putchar('\n');
      nonspace = 0;
    }
    else if (c == ' ' || c == '\t') {
      if (advance(head) == tail) {
        putchar(blank[tail]);
        tail = advance(tail);
        nonspace = 1;
        retval = EXIT_FAILURE;
      }
 
      blank[head] = c;
      head = advance(head);
    }
    else {
      while (head != tail) {
        putchar(blank[tail]);
        tail = advance(tail);
      }
      putchar(c);
      nonspace = 1;
    }
  }
 
  return retval;
}
 

上面是程序的答案:一开始看的时候不是很懂,和同事讨论了一下,搞清楚了,非常谢谢我身边的同事

主要思想: 将遇到的空格放入到队列中,如果输入的是正常的字符,我们将队列中的空格或者制表符输出,但是不容易理解的代码是下面这个

if (advance(head) == tail) {
        putchar(blank[tail]);
        tail = advance(tail);
        nonspace = 1;
        retval = EXIT_FAILURE;
      }
 
      blank[head] = c;
      head = advance(head);

是代码到当为空格或者制表符走进去的代码,我们一开始猜测它是用来做边界处理和错误处理的,我们将程序中的MAXQUEUE  改为5然后输入测试用例跑一边

如我们输入 ab       cdefg 时,中间为7个空格

发现它的输出为ab  

程序执行流程:

当输入ab的时候直接输出,当输入循环的时候,变量变化如下:

操作 head advance(head) tail block
第一个空格的时候,放入队列block数组 0 1 0 block[0] = 空格
第二个空格的时候,放入队列block数组 1 2 0 block[1] =空格
第三个空格的时候,放入队列block数组 2 3 0 block[2]=空格
第四个空格的时候,放入队列block数组 3 4 0 block[3]=空格
第五个空格的时候,放入队列block数组(注意head的变化,advance(head) = 0 了),这个时候advance(head) == tail 了,进入if语句中 4 0 0

putchar(block[tail]),弹出block[0],tail + 1;blank[0] =空格

head+1

第六个空格 0 1 1 putchar(block[tail]),弹出block[1],tail+1,blank[1]=空格,head+1
第七个空格 1 2 2 putchar(block[tail]),弹出block[2],tail+1,blank[2]=空格,head+1
第8个c 2 3 3

head != tail,putchar(3),tail+1,直到tail== 2,

这里弹出 block[3],block[4],block[0],block[1],block[2],

tail =3, 相等,然后输出c

接下来输出defg就可以了,然后retval = EXIT_FAILURE; EXIT_FAILURE 可以作为exit()的参数来使用,表示没有成功地执行一个程序。程序中设置的MAXQUEUE,表示的是最多可以消除的空格或者制表符的个数,当超出这个数量的时候,程序使用两个指针,将多余的空格和制表符输出,同时保证数组不会溢出,非常的巧妙,可以看到head和tail都是从0 1 2 3 4 0 1 2,这样转圈的变化的,感觉比较有意思
 

猜你喜欢

转载自blog.csdn.net/zpf_nevergiveup/article/details/81121043