当前位置:网站首页>>电脑技术>>C、C++语言>>我的著作 双击自动滚屏
中西文全屏幕编辑程序的设计和编制(二)

发表日期:2006年1月1日      已经有2500位读者读过此文

                               1.5 建立临时文件

    在内存中,操作系统提供的用户空间是有限的,编辑程序自身也要占用一定的空间,因此,编辑缓冲区不可能无限制地设置得很大,如果要编辑一个相当大的文件,不可能全部放在编辑缓冲区的数组内时怎么办呢?在这种情况下,就只能把文本文件的一部分放在内存中的编辑缓冲区内进行处理。由于在编辑过程中,要进行各种各样的操作,当前操作位置在文本中是经常变动的,因此,编辑缓冲区中的数组 (以下简称编辑数组) 相对于文本文件就必须是动态的。在移动的过程中,必然有一部分已编辑处理过的文本需要临时有个地方放一放,以腾出空间再读入另一部分文本。这时就必须借助于外部存储器──磁盘,在磁盘上建立两个临时文件,一个用于存放编辑数组中的文本内容之前的已读入过编辑数组的文本行,另一个用来存放编辑数组中文本内容后的已读入过内存的文本行。
    为了便于叙述,不妨假设我们在编辑一个名为 AAA.TXT 的文本文件, 就需在磁盘上建AAA.$1$ 和 AAA.$2$ 两个临时文件。假定 AAA.TXT 是一个新文件,并已定义了一个 500 行的字符串数组 ss[i][j] 作为编辑缓冲区。开始编辑时,新建立的 AAA.TXT 是一个空文件,编辑数组也是空的。我们通过键盘不断把文本输入这个编辑数组,从 ss[0] 行起,写到了 ss[499],这时文本的第 0─499 行就放在数组项 ss[0]─ss[499] 中。如果继续换行输入,编辑数组就放不下了,怎么办呢? 这就要用到临时文件了。我们可将文本第 0 行─第 199 行的共 200行从编辑数组中取出来,放到临时文件 AAA.$1$ 中去,并把编辑数组中的第 200─499 行依次前移到 ss[0]─ss[299] 中,这样编辑数组的后半部就腾出 200 行空间,可供继续输入了。当又输入 200 行后,再从编辑数组前部放 200 行到 AAA.$1$ 中去,编辑数组中留下的是文本第 400─699 行。在此过程中,要建立一个数组 wra[oa] 来存放 AAA.$1$ 每一次读写的起始位置相对于文件头的偏移量,即 wra[0]─wra[1] 为最早放入 AAA.$1$ 的 200行(文本的第 0─199 行),wra[1]─wra[2] 之间为第二次放入的内容(第 200─399 行),wra[2]为下一次写入的起始地址。图 1.2 是上述过程的示意图。

         编  辑  数  组     |          AAA.$1$
    文本行号         数组行 | 文本行号        读写地址
      xx                    |   xx
    ━━━━━━━━━━━━━━━━━━━━━━━━━
    第 0 行┏━━━┓ss[0]  |         ┄┄┄┄┄wra[0]
           ┃      ┃       |
           ┃      ┃       |
           ┃      ┃       |
           ┃      ┃       |
    第499行┗━━━┛ss[499]|
                            |
      (1)从键盘输入 500 行至编辑数组,AAA.$1$ 为空文件
    ━━━━━━━━━━━━━━━━━━━━━━━━━
           ┌───┐ss[0]  |  第 0 行┏━━━┓wra[0]
           │      │       |         ┃      ┃
    第200行┢━━━┪ss[200]|  第199行┗━━━┛wra[1]
           ┃      ┃       |
           ┃      ┃       |
    第499行┗━━━┛ss[499]|
                            |
      (2)从编辑数组前部移 200 行至临时文件 AAA.$1$
    ━━━━━━━━━━━━━━━━━━━━━━━━━
    第200行┏━━━┓ss[0]  |  第 0 行┏━━━┓wra[0]
           ┃      ┃       |         ┃      ┃
           ┃      ┃       |  第199行┗━━━┛wra[1]
    第499行┡━━━┩ss[299]|
           │      │       |
           └───┘       |
                            |
      (3)编辑数组中剩余 300 行前移
    ━━━━━━━━━━━━━━━━━━━━━━━━━
    第200行┏━━━┓ss[0]  |  第 0 行┏━━━┓wra[0]
           ┃      ┃       |         ┃      ┃
           ┃      ┃       |  第199行┗━━━┛wra[1]
           ┃      ┃       |
           ┃      ┃       |
    第699行┗━━━┛ss[499]|
                            |
      (4)再从键盘输入 200 行至编辑数组
    ━━━━━━━━━━━━━━━━━━━━━━━━━
           ┌───┐ss[0]  |  第 0 行┏━━━┓wra[0]
           │      │       |         ┃      ┃
    第400行┢━━━┪ss[200]|  第200行┣━━━┫wra[1]
           ┃      ┃       |         ┃      ┃
           ┃      ┃       |  第399行┗━━━┛wra[2]
    第699行┗━━━┛ss[499]|
                            |
      (5)将编辑数组前 200 行移至 AAA.$1$
    ━━━━━━━━━━━━━━━━━━━━━━━━━
    第400行┏━━━┓ss[0]  |  第 0 行┏━━━┓wra[0]
           ┃      ┃       |         ┃      ┃
           ┃      ┃       |  第200行┣━━━┫wra[1]
    第699行┡━━━┩ss[299]|         ┃      ┃
           │      │       |  第399行┗━━━┛wra[2]
           └───┘       |
                            |
      (6)编辑数组中剩余 300 行前移
    ━━━━━━━━━━━━━━━━━━━━━━━━━

                  图 1.2 新文件的输入过程

    从编辑数组移指定行数到临时文件 1 是通过函数 wfp1()完成的:

#define Q3 (QB*2/5)              /* 每次读写临时文件的行数 */
........
wfp1()                           /* 将内存数组上部 Q3 行写入临时文件 1 */
{
  fseek(fp1,wra[oa],SEEK_SET);   /* 指针移到写入起始位置 */
  write_to(0,Q3,fp1);            /* 写 Q3 行到 fp1 */
  wra[++oa]=ftell(fp1);          /* 记录下一次写入起始位置 */
  movbk(0,Q3);                   /* 剩下的数组前移 Q3 行 */
  ss_x-=Q3;                      /* 当前行数组行号减少 j */
  ss_max-=Q3;                    /* 数组行最大行号减少 j */
}

    库函数 fseek() 把本次写入 fp1 的起始位置指针移至数组 wra[oa] 记录的位置,参数 SEEK_SET 为从文件头开始按给定的偏移量移动文件读写指针位置。用库函数 ftell() 测出临时文件 fp1 写入指定行后的读写指针位置,并记入数组 wra[oa] 中,oa 已用增量运算符 ++ 增 1。wfp1() 里调用了函数 write_to(),它的作用是把编辑数组中从指定行起的一定数量的文本行写入一个文本文件中去。

write_to(int a,int b,FILE *f)    /* 把数组第 a 行起的 b 行写入文件 f */
{
  int i;
  ........
  for(i=a;i<a+b;i++)  {          /* 从 a 行起循环 b 次 */
     fputs(ss[i],f);             /* 将该行字符串写入文件 f */
  }
  ........
}

    数组中各行前移是由函数 movbk()实现的:

movbk(int s,int a)                             /* 数组 s+a 行起前移 a 行 */
{
   int i;
   for(i=s;i<QB-a;i++) strcpy(ss[i],ss[i+a]);  /* 前移 a 行,复盖原行 */
   while(i<QB)   *ss[i++]=0;                   /* 编辑数组剩余各行清为空行 */

    这样似乎我们已经突破了 500 行编辑数组的限制,可以编辑长文件了,但是事实上并不是如此简单。如果这时我们又需要回过头来修改第 100 行的地方,而现在编辑数组里装的是第400─699 行,又怎么办呢?这时就必须用到第二个临时文件 AAA.$2$,先把文本第 500 行─第 699 行的共 200 行从编辑数组中取出放入 AAA.$2$,将编辑数组中剩余的第  400─499 行下移到 ss[200]─ss[299] 处, 然后把 AAA.$1$ 中从偏移地址 wra[1] 起的 200 行读出放入编辑数组 ss[0]─ss[199] 处, AAA.$1$ 的当前读写地址由 wra[2] 变为 wra[1]。对 AAA.$2$ 的读写位置也要建立一个数组 wrb[ob] 来存放,它的当前读写位置已由初始的 wrb[0] (等于0),变成 wrb[1]。这时编辑数组中放的文本行是第 200─499 行。还要再进行一次这样的过程才能把第 100 行移入编辑数组。(如图 1.3)

       编  辑  数  组     |         AAA.$1$        |         AAA.$2$
     xx            数组行 |   xx           读写地址|    xx          读写地址
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  第400行┏━━━┓ss[0]  | 第 0 行┏━━━┓wra[0]| 第500行┏━━━┓wrb[0]
  第499行┡━━━┩ss[99] |        ┃      ┃      |        ┃      ┃
         │      │       | 第200行┣━━━┫wra[1]| 第699行┗━━━┛wrb[1]
         │      │       |        ┃      ┃      |
         │      │       | 第399行┗━━━┛wra[2]|
         └───┘       |                        |
                          |                        |
   (1)编辑数组后部 200 行移至临时文件 AAA.$2$
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
         ┌───┐ss[0]  | 第 0 行┏━━━┓wra[0]| 第500行┏━━━┓wrb[0]
         │      │       |        ┃      ┃      |        ┃      ┃
  第400行┢━━━┪ss[200]| 第200行┣━━━┫wra[1]| 第699行┗━━━┛wrb[1]
  第499行┡━━━┩ss[299]|        ┃      ┃      |
         │      │       | 第399行┗━━━┛wra[2]|
         └───┘       |                        |
                          |                        |
   (2)编辑数组剩余部分后移 200 行,腾出前 200 行空间  
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  第200行┏━━━┓ss[0]  | 第 0 行┏━━━┓wra[0]| 第500行┏━━━┓wrb[0]
         ┃      ┃       |        ┃      ┃      |        ┃      ┃
         ┃      ┃       | 第199行┗━━━┛wra[1]| 第699行┗━━━┛wrb[1]
  第499行┡━━━┩ss[299]|                        |
         │      │       |                        |
         └───┘       |                        |
                          |                        |
   (3)从 AAA.$1$ 取回 200 行至编辑数组前部
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  第200行┏━━━┓ss[0]  | 第 0 行┏━━━┓wra[0]| 第500行┏━━━┓wrb[0]
  第299行┡━━━┩ss[99] |        ┃      ┃      |  (699) ┃      ┃
         │      │       | 第199行┗━━━┛wra[1]| 第300行┣━━━┫wrb[1]
         │      │       |                        |        ┃      ┃
         │      │       |                        | 第499行┗━━━┛wrb[2]
         └───┘       |                        |
                          |                        |
   (4)再将编辑数组后 200 行移至临时文件 AAA.$2$
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
         ┌───┐       | 第 0 行┏━━━┓wra[0]| 第500行┏━━━┓wrb[0]
         │      │       |        ┃      ┃      |  (699) ┃      ┃
  第200行┢━━━┪ss[200]| 第199行┗━━━┛wra[1]| 第300行┣━━━┫wrb[1]
  第299行┡━━━┩ss[299]|                        |        ┃      ┃
         │      │       |                        | 第499行┗━━━┛wrb[2]
         └───┘       |                        |
                          |                        |
   (5)编辑数组中剩余行后移 200 行   
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  第 0 行┏━━━┓ss[0]  |        ┄┄┄┄┄wra[0]| 第500行┏━━━┓wrb[0]
         ┃      ┃       |                        |  (699) ┃      ┃
         ┃      ┃       |                        | 第300行┣━━━┫wrb[1]
  第299行┡━━━┩ss[299]|                        |        ┃      ┃
         │      │       |                        | 第499行┗━━━┛wrb[2]
         └───┘       |                        |
                          |                        |
   (6)再从 AAA.$1$ 取回至编辑数组前部 200 行
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

                    图 1.3 编辑内存数组移动时临时文件的作用

    两个临时文件的读写都遵循“先入后出、后入先出”的原则。要实现以上的各过程,就有必要建立从编辑数组中取出指定行数写入文件、从文件中读出一块记录放入编辑数组指定区域和把编辑数组中的行移动位置的子模块。
   编辑数组取指定行写入临时文件 2 时调用了函数 wfp2(),它和 wfp1() 的区别在于: wfp1() 是从编辑数组前部取 Q3 行放入 fp1,而 wfp2() 则是从编辑数组后半部取 Q3 行写入 fp2 。

wfp2()                                    /* 写 Q3 行到临时文件 2 */
{
  int i;
  fseek(fp2,wrb[ob],SEEK_SET);            /* 定 fp2 指针到本次读写位置 */
  write_to(ss_max-Q3+1,Q3,fp2);  /* 从数组 ss_max-Q3+1 行起,写 Q3 行到 fp2 */
  if(xx-ss_x+ss_max==ttl_x) fputc(0,fp2); /* 文末行以 ''''\0'''' 定界 */
  wrb[++ob]=ftell(fp2);          /* 记录下一次写起始地址到指针数组 wrb[ ] */
  ss_max-=Q3;                             /* 数组行相应减少 */
  for(i=ss_max+1;i<QB;i++)  *ss[i]=0;     /* 数组后部未用行初始化 */
}

    从一个文件里读出指定行文本放入编辑数组指定区域的函数为 read_from(),该函数从文件中当前读写位置逐行读出,放入编辑数组。函数 read_from() 的返回值是实际读出的行数。read_from() 前的类型说明 int 也可省略,因为 C 语言默认的缺省类型为 int。

int read_from(int a,int b,FILE *f) /* 从文件f读入b行放入数组ss[]的第a行起 */
{
  int i,j;
  ........
  for(i=a;i<a+b;i++)  {            /* 逐行读出 */
    if(fgets(ss[i],HC,f)==NULL) {  /* 从f读出一行,放入数组,如读失败 */
      j=0;
      while(ss[i-1][j]) {          /* 逐字节对比文末行,字符值为真(非 0)则循环 */
        if(ss[i-1][j]==0x1A) {     /* 如为文件结束符 */
          ss[i-1][j]=0;            /* 用 ''''\0'''' 替代 */
          break;                   /* 跳出 while 循环 */
        }
        j++;                       /* 后移一字节 */
      }
      break;                       /* 跳出 for 循环 */
    }
  }
  ........
  return i-a;                      /* 返回读出行数 */
}

    程序中的 while(ss[i-1][j]) 是 C 语言风格的写法,相当于 while(ss[i-1][j]!=0),其意思是 ss[i-1][j] 为“真”则循环。C 语言进行判断时把不等于 0 称为“真”,等于 0 称为“假”。在后面的程序中,还可以看到如把表达式 if(chg!=0) 写成 if(chg),把 if(cc.ch[0]==0) 写成 if(!cc.ch[0]) 的例子。
    文本行的读出用库函数 fgets() 实现,从上述程序中可以看出,fgets() 带有三个形参:第一个是放读出的字符串的字符型数组,第二个是读出的最大字符数 HC(=255),第三个是读写的文件指针。fgets() 对行的判断是以换行符 0x0A 或空字符 ''''\0'''' 为界的,在从当前读写位置起的 HC 个字符中没有 0x0A 或 ''''\0'''' 时,它就从 f 中读出 HC 个字符,如读出过程中遇到这两种符号,则读出的字符串到此为止,fgets() 返回指向串的指针。当文件读完时,如继续读,则 fgets() 返回 NULL。NULL 的值为 0,定义在头文件 stdio.h 中。
    在 read_from() 中对文末行进行了处理,去除了文件结束符 0x1A。从文件读出的过程可以看出,BJ 编辑的文本文件在编辑数组中,除文末行以 ''''\0'''' 结尾,其余各行均以硬回车换行符 0x0D0A 或软回车换行符 0x8D0A 并加 ''''\0'''' 结束。

                            1.6 一个老文件的编辑过程

    如果是编辑一个已有的老文件 BBB.TXT,这个文件又比较长,通常总是先把文首开始的一部分放到编辑数组中,同时又给编辑数组留一定的空间,如读入 300 行,留 200 行空间。这样做的好处是: 在编辑过程中对编辑区数组插入一些行或删除一些行时,只须对编辑数组中的部分行进行移动,而不必对整个文本文件进行重新排列,而且,只须在编辑区域将要移出内存数组、因增删而使编辑数组将发生溢出或行数太少将影响屏幕显示时才对原文件或临时文件进行读写,而不必频繁地读盘、写盘。
    假定老文件 BBB.TXT 有 1001 行 (行号 0─1000),两个临时文件分别是 BBB.$1$ 和 BBB.$2$,开始时从 BBB.TXT 读 300 行放入编辑数组中。这时如要修改第 600 行的内容,就要使编辑区域向文末方向移动,把第 600 行调入内存中的编辑数组,其过程如图 1.4。

     BBB.TXT     |    编辑数组     |     BBB.$1$      |     BBB.$2$
   xx            |  xx      数组行 |  xx     读写地址 |  xx      读写地址
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     |   0┏━┓ss[0]  |    ┄┄┄wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    ┃  ┃       |                  |
      ┃  ┃     |    ┃  ┃       |                  |
   300┠─┨     | 299┡━┩ss[299]|                  |
      ┃  ┃     |    │  │       |                  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (1)从 BBB.TXT 读 300 行至编辑数组。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     |    ┌─┐       |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     | 200┢━┪ss[200]| 199┗━┛wra[1]  |
   300┠─┨     | 299┡━┩ss[299]|                  |
      ┃  ┃     |    │  │       |                  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (2)将编辑数组前面 200 行放入临时文件 BBB.$1$
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 200┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     | 299┡━┩ss[99] |    ┃  ┃        |
      ┃  ┃     |    │  │       | 199┗━┛wra[1]  |
   300┠─┨     |    │  │       |                  |
      ┃  ┃     |    │  │       |                  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (3)编辑数组中剩余行前移。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 200┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    ┃  ┃       |    ┃  ┃        |
      ┃  ┃     |    ┃  ┃       | 199┗━┛wra[1]  |
      ┃  ┃     | 499┡━┩ss[299]|                  |
      ┃  ┃     |    │  │       |                  |
   500┠─┨     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (4)再从 BBB.TXT 中读 200 行放入编辑数组。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     |    ┌─┐       |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     | 400┢━┪ss[200]| 200┣━┫wra[1]  |
      ┃  ┃     | 499┡━┩ss[299]|    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┗━┛wra[2]  |
   500┠─┨     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (5)将编辑数组前部 200 行移入临时文件 BBB.$1$。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 400┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     | 499┡━┩ss[99] |    ┃  ┃        |
      ┃  ┃     |    │  │       | 200┣━┫wra[1]  |
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┗━┛wra[2]  |
   500┠─┨     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (6)编辑数组中剩余部分前移。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 400┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    ┃  ┃       |    ┃  ┃        |
      ┃  ┃     |    ┃  ┃       | 200┣━┫wra[1]  |
      ┃  ┃     | 699┡━┩ss[299]|    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┗━┛wra[2]  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (7)再从 BBB.TXT 中读 200 行到编辑数组中。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

                   图 1.4 一个老文件的编辑过程示意图之一

    这时第 600 行已调入编辑数组,可以对其进行修改操作。如果接着又要修改第 300 行,就要再将编辑区域向文首方向移动,如图 1.5 所示。

     BBB.TXT     |    编辑数组     |     BBB.$1$      |     BBB.$2$
   xx            |  xx      数组行 |  xx     读写地址 |  xx      读写地址
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 400┏━┓ss[0]  |   0┏━┓wra[0]  | 500┏━┓wrb[0]
      ┃  ┃     | 499┡━┩ss[99] |    ┃  ┃        |    ┃  ┃
      ┃  ┃     |    │  │       | 200┣━┫wra[1]  | 699┗━┛wrb[1]
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┗━┛wra[2]  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (8)将编辑数组中后 200 行放入临时文件 BBB.$2$。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     |    ┌─┐       |   0┏━┓wra[0]  | 500┏━┓wrb[0]
      ┃  ┃     |    │  │       |    ┃  ┃        |    ┃  ┃
      ┃  ┃     | 400┢━┪ss[200]| 200┣━┫wra[1]  | 699┗━┛wrb[1]
      ┃  ┃     | 499┡━┩ss[299]|    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┗━┛wra[2]  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (9)编辑数组中剩余部分后移 200 行,让出上部 200 行空间。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 200┏━┓ss[0]  |   0┏━┓wra[0]  | 500┏━┓wrb[0]
      ┃  ┃     |    ┃  ┃       |    ┃  ┃        |    ┃  ┃
      ┃  ┃     |    ┃  ┃       | 199┗━┛wra[1]  | 699┗━┛wrb[1]
      ┃  ┃     | 499┡━┩ss[299]|                  |
      ┃  ┃     |    │  │       |                  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (10)从临时文件 BBB.$1$ 内 wra[1] 位置处起读 200 行放入编辑数组前部。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

                    图 1.5 一个老文件的编辑过程示意图之二

    此时文本的第 0─199 行在临时文件 BBB.$1$ 中, 第 200─499 行在编辑数组中,第500─699 行在临时文件 BBB.$2$ 中,剩余的部分在原始文件 BBB.TXT 中。第 300 行已调入编辑数组,可对其进行编辑操作了。
    再接下去如果我们要把编辑区域移至文末,过程如图 1.6。

     BBB.TXT     |    编辑数组     |     BBB.$1$      |     BBB.$2$
   xx            |  xx      数组行 |  xx     读写地址 |  xx      读写地址
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     |    ┌─┐       |   0┏━┓wra[0]  | 500┏━┓wrb[0]
      ┃  ┃     |    │  │       |    ┃  ┃        |    ┃  ┃
      ┃  ┃     | 400┢━┪ss[200]| 200┣━┫wra[1]  | 699┗━┛wrb[1]
      ┃  ┃     | 499┡━┩ss[299]|    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┗━┛wra[2]  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (11)将编辑数组前 200 行移至临时文件 BBB.$1$。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 400┏━┓ss[0]  |   0┏━┓wra[0]  | 500┏━┓wrb[0]
      ┃  ┃     | 499┡━┩ss[99] |    ┃  ┃        |    ┃  ┃
      ┃  ┃     |    │  │       | 200┣━┫wra[1]  | 699┗━┛wrb[1]
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┗━┛wra[2]  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (12)编辑数组中剩余行前移。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 400┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    ┃  ┃       |    ┃  ┃        |
      ┃  ┃     |    ┃  ┃       | 200┣━┫wra[1]  |
      ┃  ┃     | 699┡━┩ss[299]|    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┗━┛wra[2]  |
      ┃  ┃     |    └─┘       |                  |
      ┃  ┃     |                 |                  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (13)从临时文件 BBB.$2$ 中读 200 行放入编辑数组中。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     |    ┌─┐       |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     | 600┢━┪ss[200]| 200┣━┫wra[1]  |
      ┃  ┃     | 699┡━┩ss[299]|    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┣━┫wra[2]  |
      ┃  ┃     |    └─┘       |    ┃  ┃        |
      ┃  ┃     |                 | 599┗━┛wra[3]  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (14)编辑数组前 200 行移至临时文件 BBB.$1$ 中。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 600┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     | 699┡━┩ss[99] |    ┃  ┃        |
      ┃  ┃     |    │  │       | 200┣━┫wra[1]  |
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┣━┫wra[2]  |
      ┃  ┃     |    └─┘       |    ┃  ┃        |
      ┃  ┃     |                 | 599┗━┛wra[3]  |
   700┠─┨     |                 |                  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (15)编辑数组剩余行前移。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 600┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    ┃  ┃       |    ┃  ┃        |
      ┃  ┃     |    ┃  ┃       | 200┣━┫wra[1]  |
      ┃  ┃     | 899┡━┩ss[299]|    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┣━┫wra[2]  |
      ┃  ┃     |    └─┘       |    ┃  ┃        |
      ┃  ┃     |                 | 599┗━┛wra[3]  |
      ┃  ┃     |                 |                  |
      ┃  ┃     |                 |                  |
   900┠─┨     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (16)从 BBB.TXT 当前读写位置起读 200 行移入编辑数组。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     |    ┌─┐       |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     | 800┢━┪ss[200]| 200┣━┫wra[1]  |
      ┃  ┃     | 899┡━┩ss[299]|    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┣━┫wra[2]  |
      ┃  ┃     |    └─┘       |    ┃  ┃        |
      ┃  ┃     |                 | 599┣━┫wra[3]  |
      ┃  ┃     |                 |    ┃  ┃        |
      ┃  ┃     |                 | 799┗━┛wra[4]  |
   900┠─┨     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (17)编辑数组前 200 行移至临时文件 BBB.$1$。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 800┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     | 899┡━┩ss[99] |    ┃  ┃        |
      ┃  ┃     |    │  │       | 200┣━┫wra[1]  |
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┣━┫wra[2]  |
      ┃  ┃     |    └─┘       |    ┃  ┃        |
      ┃  ┃     |                 | 599┣━┫wra[3]  |
      ┃  ┃     |                 |    ┃  ┃        |
      ┃  ┃     |                 | 799┗━┛wra[4]  |
   900┠─┨     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (18)编辑数组中剩余行前移。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    0 ┏━┓     | 800┏━┓ss[0]  |   0┏━┓wra[0]  |    ┄┄┄wrb[0]
      ┃  ┃     |    ┃  ┃       |    ┃  ┃        |
      ┃  ┃     |1000┡━┩ss[200]| 200┣━┫wra[1]  |
      ┃  ┃     |    │  │       |    ┃  ┃        |
      ┃  ┃     |    │  │       | 399┣━┫wra[2]  |
      ┃  ┃     |    └─┘       |    ┃  ┃        |
      ┃  ┃     |                 | 599┣━┫wra[3]  |
      ┃  ┃     |                 |    ┃  ┃        |
      ┃  ┃     |                 | 799┗━┛wra[4]  |
      ┃  ┃     |                 |                  |
  1000┗━┛     |                 |                  |
                 |                 |                  |
    (19)从 BBB.TXT 当前读写位置起将剩余 101 行读入编辑数组。
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

                   图 1.6 一个老文件的编辑过程示意图之三

    上述示意图形象地描述了编辑缓冲区数组在文本中前后移动的过程,以及临时文件所起的作用。在编辑数组向文末方向移动时,先把编辑数组中的行移一些到第一个临时文件中,以让出一部分空间,当第二个临时文件中还有内容时从它里面读指定行数至编辑数组中,当 wrb[ob] 中的数组号 ob=0 (即第二个临时文件为空) 时,从原始文件的当前读写指针位置起读指定行数至编辑数组中。如原始文件亦已读完,编辑区域不再移动。当编辑区域向文首方向移动时,如第一个临时文件读写位置数组 wra[oa] 中的数组号 oa=0,则说明文首第0 行已装入编辑数组,编辑区域不能再前移。BBB.TXT 读完后,置标志 fp_end=1,程序不再对 BBB.TXT 进行读写。


相关专题: 我的著作
专题信息:
  C语言速成(第三章 程序控制语句)(2006-1-1 13:51:28)[9418]
  C语言速成(第七章 联合、枚举和自定义数据类型)(2006-1-1 13:51:46)[10048]
  C语言速成(第六章 结构)(2006-1-1 13:52:05)[8827]
  C语言速成(第五章 指针)(2006-1-1 17:28:54)[4568]
  C语言速成(第四章 数组)(2006-1-1 13:52:42)[4712]

相关信息:
 没有相关信息
  打印本页
设为首页 | 加入收藏 | 联系我们 | 管理入口
皖ICP备05018956号
Copyright © 2003 J.W.SHEN All Rights Reserved
后台管理系统 V1.0 制作