摘要:在linux系统中,我们经常用到more命令来显示文件内容,那么more命令是如何实现的呢?如何在终端反显一个字符串,比如“more”?如何在输入重定向的时候从键盘读入命令?本文通过more命令的实现来讲解相关知识。附录中是本文所使用的代码。
1)和shell程序不同,程序名称本身也是命令行参数的一个,从0开始计算
2)关于设备/dev/tty
/dev/tty文件的存在,有一个特殊的用法:
当标准输入stdin和标准输出stdout被重定向时,我们仍然可以通过/dev/tty文件而实现对键盘的读取和对显示器的输出!
3)fgets函数
4)fputs函数
5)getc函数
6)char *arv[] 关于二维数组,指针与指向指针的指针:
注意,申明了指针,这个指针“对应的数组”的存储空间被没有分配
二维数组的本质:
int*p, a[3][4]为例
所有的数组都看作是一维数组,只不过数组元素不同;而为数组的元素是“一行”而不是“一个”。
C语言中,在函数体中或在函数外部定义的一维数组名是一个地址常量,其值为数组第一个元素的地址,此地址的基类型就是数组元素的类型(所以我们在申明二维数组的时候可以省略第一维,但不能省略第二维度,因为要确定数组元素的类型)。
因此,赋值语句p=a[i];是合法的。我们已知a[i]也可以写成:*(a+i),故以上赋值语句也可写成:p=*(a+i);
二维数组名应理解为一个行指针。在表达式a+1中,数值1的单位应是4×2个字节,而不是2个字节。赋值语句p=a;是不合法的,因为p和a的基类型不同。再次申明:基类型不同的两个变量之间不能直接赋值,从这个角度说,数组类型不是一个单独的类型而是包含了很多不同的类型。
通过地址来引用二维数组元素若有以下定义:inta[3][4],i,j;且当0≤i<3、0≤j<4,则a数组元素可用以下五种表达式来引用:(1)a[i][j](2)*(a[i]+j)(3)*(*(a+i)+j)(4)(*(a+i))[j](5)*(&a[0][0]+4*i+j)
二维数组与指针数组:通过建立一个指针数组来引用二维数组元素若有以下定义:int*p[3], a[3][2], i,j;在这里,说明符*p[3]中,也遵照运算符的优先级,一对[]的优先级高于*号,因此p首先与[]结合,构成p[3],说明了p是一个数组名,系统将为它开辟3个连续的存储单元;在它前面的*号则说明了数组p是指针类型,它的每个元素都是基类型为int的指针。若满足条件:0≤i<3,则p[i]和a[i]的基类型相同,p[i]=a[i]是合法的赋值表达式。
二维数组做函数参数:
VoidFunc(int array[3][10]);
voidFunc(int array[][10]);
可以省略一维空间的大小,但是不能第二维,它是3个长度为10的数组,不是10个长度为3的数组;同样可以用int**p来进行
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#define LINELEN 512
#define PAGELEN 24
void do_more(FILE *fp);
int see_more(FILE *fp);
int main(int arc,char *arv[])
{
FILE *fp=NULL;
if(arc==1)
do_more(stdin);
else
{
fp=fopen(arv[1],"r");
if(fp==NULL)
{
printf("can't open file %s",*arv);
exit(0);
}
do_more( fp);
fclose(fp);
}
return 0;
}
void do_more(FILE *fp)
{
char line[LINELEN];
FILE *fptty;
int num_line=0;
int see_more();
int reply=0;
fptty=fopen("/dev/tty","r");
while (fgets(line,LINELEN,fp))
{
if(PAGELEN==num_line)
{
reply=see_more(fptty);
if(reply==0)
break;
num_line-=reply;
}
if(fputs(line,stdout ) == EOF )
exit(1);
num_line++;
}
}
int see_more(FILE *cmd)
{
int c;
printf("\033[7m more?\033[m");
while( ( c=getc(cmd))!=EOF)
{
if(c=='q')
return 0;
if(c==' ')
return PAGELEN;
if(c=='\n')
return 1;
return 0;
}
}