第一章的一道练习题,开始无论如何都理解不了这道题的意思,直到用VS一步一步的调试着看:
???? 1-21:
编写程序entab,将空格串替换为最少数量的空格和制表符,但要保持单词之间的间隔不变。假设制表符终止位的位置为8(#define TABINC 8)。当使用一个制表符或者一个空格都可以到达下一个制表符终止位的时,选用哪一种替换字符较好?
例如:hello world
hello和world之间有9个空格,这个打印的时候,先打印出hello,然后遇到了第一个空格,此时pos = 6,且pos不在制表符终止位上,所以nb++;
直到pos = 8 = TABINC时,令nb = 0,nt++,既是将hello后的三个空格换成一个tab。
从pos = 9到pos = 15之间的六个空格,还是六个空格,不做改变。
随后打印出world,程序结束。
如:he is a boy
he后是一个tab,is后一个tab和两个空格,a后8个空格一个tab。
当pos =3时,遇到第一个tab,令nb = 0,然后根据公式:pos = pos+(TABINC-(pos-1)%TABINC)-1得出pos=8,既是直接打印一个制表符,并跳到 TABINC处。
接着打印出is。
pos=11时遇到tab,由公式得出pos=16,跳到第二个TABINC处。
打印完两个空格后遇到a,pos=19。
a后打印了五个空格后到了第三个TABINC,于是nb = 0,nt++,此时pos=24。
后边三个空格,打印完后pos=28,遇到\t,于是将之前积累的制表符和当前遇到的这个制表符打印出来。
最后打印出boy,程序结束。
1 #include <stdio.h> 2 #define TABINC 8 3 //将空格串替换成最少数量的制表符和空格,但要保持单词之间的间隔不变 4 int main(int argc,char* argv[]) 5 { 6 int c,nb,nt,pos; 7 8 nb = 0; 9 nt = 0; 10 for(pos = 1;(c = getchar())!=EOF;++pos) 11 { 12 if(c == ‘ ‘) 13 { 14 if(pos % TABINC != 0) 15 { 16 ++nb; 17 }else 18 { 19 nb = 0; 20 ++nt; 21 } 22 }else { 23 for (;nt>0;--nt) { 24 putchar(‘\t‘); 25 } 26 if(c == ‘\t‘) 27 nb = 0; 28 else 29 for(;nb>0;--nb) 30 putchar(‘ ‘); 31 putchar(c); 32 if(c == ‘\n‘) 33 pos = 0; 34 else if (c == ‘\t‘) { 35 pos = pos + (TABINC - (pos - 1) % TABINC) - 1; 36 } 37 38 } 39 } 40 }
entab
程序主要是要将全部的空格找出。然后当pos递增到一个TABINC的倍数的时候,就把空格串替换成一个制表符。
遇到非空格字符时,程序先将遇到这个字符之前的所有空格和制表符打印出来后,再打印这个字符。
若当前字符是一个换行符,则注意重新将pos值设为1.
当遇到一个制表符时程序只需将此前积累的制表符和当前遇到的这个制表符打印出来。
如果只需一个空格就能到达下一个制表位,我们选择把他替换成一个制表符,因为这有助于避免特殊情况。