练习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,这样转圈的变化的,感觉比较有意思