一起talk C栗子吧(第一百九十五回:C语言实例--DIY less命令四 )


各位看官们,大家好,上一回中咱们说的是DIY less命令的例子,这一回咱们继续说该例子。闲话休提,言归正转。让我们一起talk C栗子吧!


看官们,我们在上一回中提到了让文件流回退的方法,不过没有详细说明使用什么方法,这一回中我们将详细介绍这种方法。

我当时想到了两种方法,它们分别是缓冲法和跳跃法。这时有看官睁大了眼睛在看我,我估计这位看官是不明白这些方法,而且连方法的名字也没有听过。我想说,这不能怪这位看官,因为这些方法的名字是我起的,正所谓不知者无罪嘛。好了,不说这些无用的了,我们抓紧时间介绍这些方法吧。

1.缓冲法

首先定义一个数组,数组中的每个元素存放文件中一整行的内容,数组的下标就是文件中的行数,如果想看文件中某一行中的内容,只需要找数组下标就可以。比如,我们想让文件的内容回退一行,那么只需要把数组的下标减一,然后查看与下标匹配的内容就可以。

该方法中使用了数组来作为缓冲,因此我给它起名为缓冲法。不过该方法有个缺点,不知道有没有看官发现呢?估计,我自创的这东西,大家可能还是不习惯,那么我来告诉大家。该方法的性能不够好,或者直接点说,它会占用很大的内存空间。因为我需要定义一个很大的数组才能存放文件中的内容,这显然是很浪费内存空间的。鉴于这个原因,我没有采用该方法。如果哪位看官感兴趣,可以使用这个思路,自己动手实现一下。我就不通过代码演示了。

2.跳跃法

我们首先跳转到文件头,跳转时使用fsetpos函数就可以,我们在前面章回中介绍过,相信各位看官还记得,不过该函数需要一个关于文件流位置的参数,而且该位置是文件头的位置。大家还记得,我们在读取文件内容的时候留下的悬念吗?现在该是解释这个悬念的时候了:

我们当时在打开文件后,读取文件内容前使用fgetpos函数获取了文件头的位置,现在正好派上用场了。跳转到文件头后,我们再向前移动x行,这个x行到底是多少行?我们有个计算公式x=y-1;完了,这回是彻底的完了,x还没有计算出来,又来了个y。y是什么呢?大家还记得上一回中我们介绍如何响应j命令时提到的变量back_count吗?它是用来统计j命令运行的次数。这里的y就等于back_count的值。为什么它们的值是相等的呢?该方法的难点就在这里,大家一下子想不到是正常的,接下来我们通过画图的方法
来给大家演示其中的原理:
[窗口A]

---------------------------------------------------------------
|1.
|2.
|3.
|...
|11.
---------------------------------------------------------------

我们假设上面的图形是一个终端窗口,在该窗口中使用less命令打开文件,该窗口中显示了文件第1行到第11行的内容。这个时候back_count的值为0,我们执行j命令后文件向下滚动一行,back_count的值增加1,也就是y的值增加1。我们这里的终端窗口如下所示:
[窗口B]

---------------------------------------------------------------
|2.
|3.
|4.
|...
|12.
----------------------------------------------------------------

这个时候如果我们运行k命令时,它又会回复到窗口A的样子,那么依据公式:x=y-1可以得到x的值为0,也就文件头。当然了,有客官会问:当y等于0,也就是在窗口A中执行k命令会是什么样子?它不会有变化的,因为已经是文件头了。不过,有一点需要注意,如果一直执行j命令到达文件末尾后,会自动结束less命令,回到DIY的shell中。

看官们,在该方法中大家要把握一个不变的东西,那就是窗口的大小。我们可以这样想,文件的行数是固定的,我们在文件上使用了一个固定大小的窗口来显示文件中的内容,执行j和k命令相当于是在滑动窗口。在这个思想的基础上,理解我自创的跳跃法会更加容易一些。思路介绍过了,图形也演示过了,接下来我们展示该方法的核心代码,在代码面前所有的一切将会显现在你眼前:

            else if(cmd == 'k')
            {
                back_count -= 1; // reduce the count of k cmd
                current_line = 0;

                //go back to the beaging of file,and then go to the new location for k cmd
                fsetpos(fp,&begin_pos);
                while(current_line++ < back_count)
                {
                    fgets(buf,PATH_SIZE,fp);
                }
                //get the right location of k cmd, and then set this location
                fgetpos(fp,&pos);  
                fsetpos(fp,&pos);  

                current_line = 0; // it is used as temp, must keek to 0
            }

各位看官,关于DIY less命令的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值