把较长的输入行“折”成短一些的两行或多行

     源自《The C Programming Language》P25 pr1-22:

 

     编写一个程序,把较长的输入行“折”成短一些的两行或多行,折行的位置在输入行的第n列之前的最后一个非空格符之后。

     要保证程序能够智能地处理输入行很长以及在指定的列前没有空格或是制表符的情况。

     参考代码:

     

main.c
1 #include <stdio.h>
2
3 #define MAXCOL 10 //输入行的折行位置,即输入行的第n列
4 //程序将在输入行的每一处第n列之前对该输入行折行
5 #define TABINC 8 //'\t'等价8个空格
6
7 char line[MAXCOL]; //输入行
8
9 int exptab(int pos);
10 int findblnk(int pos);
11 int newpos(int pos);
12 void printl(int pos);
13
14 int main()
15 {
16
17 int c, pos;
18
19 pos = 0; //pos:程序在文本行中的当前位置
20 while((c = getchar()) != EOF)
21 {
22 line[pos] = c; //存储当前支付
23 if(c == '\t')
24 pos = exptab(pos); //将制表符扩展为空格
25 else if(c == '\n') //每遇到一个换行符就将此前输入的文本打印
26 {
27 printl(pos);
28 pos = 0;
29 }
30 else if(++pos >= MAXCOL)//当pos到达MAXCOL时,对输入行进行“折叠”
31 {
32 pos = findblnk(pos-1);
33 printl(pos);
34 pos = newpos(pos);
35 }
36 }
37
38 return 0;
39 }
40
41 //函数printl:打印输出从位置0~pos-1之间的字符
42 void printl(int pos)
43 {
44 int i;
45
46 for(i = 0; i < pos; ++i)
47 putchar(line[i]);
48 if(pos > 0)
49 putchar('\n');
50 }
51
52 //函数exptab:将'\t'扩展成空格,标记'\t'所包含的最后一个空格的下标
53 int exptab(int pos)
54 {
55 line[pos] = ' ';
56 for(++pos; pos < MAXCOL && pos % TABINC != 0; ++pos)
57 line[pos] = ' ';
58 if(pos < MAXCOL)
59 return pos;
60 else
61 {
62 printl(pos);
63 return 0;
64 }
65 }
66
67 //函数findblnk:从输入行的pos处开始倒退寻找一个空格(目地是为了保持折行位置单词的完整),
68 //如果找到了一个空格,就返回紧跟在该空格符后面的那个位置的下标;如果没找到,返回MAXCOL
69 int findblnk(int pos)
70 {
71 while(pos > 0 && line[pos] != ' ')
72 --pos;
73 if(pos == 0)
74 return MAXCOL;
75 else
76 return pos + 1;
77 }
78
79 //函数newpos:调整输入行,把从位置pos开始的字符复制到下一个输出行的开始,返回变量pos的新值
80 int newpos(int pos)
81 {
82 int i, j;
83
84 if(pos <= 0 || pos >= MAXCOL)
85 return 0;
86 else
87 {
88 i = 0;
89 for(j = pos; j < MAXCOL; ++j)
90 {
91 line[i] = line[j];
92 ++i;
93 }
94
95 return i;
96 }
97 }

     分析:

     1,  对题意“折行的位置在输入行的第n列之前的最后一个非空格符之后”的理解:比如每隔10个字符折成一行,

          如果这10个字符中间没有空格,则输出;如果有一个空格,则输出位置0开始的字符到本空格处之间的所有字符;

          如果有若干个空格,则输出位置0到最后一个空格处之间所有字符。

          例如:输入:abcd/tehghjk,

                   输出:abcd

                            ehghjk

                   输入:abc def ghk

                   输出:abc def

                            ghk

                   输入:abc            fekgl(中间有7个空格)

                   输出:abc

                              fekgl

      2,  对从输入缓冲区中读取的每个字符c,依据c == '/t',c == '/n',++pos >= MAXCOL分成三类处理。

      缺陷:如同分析1中的第三种输入输出情况,第二行输出时,头部输出了空格,可以将输出行头部的空格去掉,将会更加严谨。

posted on 2011-04-26 05:04  将军之盾  阅读(617)  评论(1编辑  收藏  举报