⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 show.c

📁 通用的全屏幕文件浏览程序
💻 C
字号:
#include <ctype.h>
#include <curses.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <stdlib.h>
#include <tam/kcodes.h>

/***************通用[显示/查询/修改/插入/删除/打印]函数***********************
功    能:在屏幕指定区域显示文本文件内容,按光标键移动显示内容,
	 光标所在行高亮度显示,可对光标所在行进行插入删除修改
调用原形:int SHOW( char * file_name,
		   char * xs_head1,
		   char * cx_head2,
		   char * dy_head,
		   int  starty,int startx,int maxrow,int maxcol, 
		   (int *insert_fun)(),
	           (int *delete_fun)(),
		   (int *update_fun)(),
		   (int *enter_fun)() )
作    者:谷维强
开发时间:2001.01.26  update:2001.07.29 
传入参数:file_nane  ---被显示的文件名
	 xs_head1   ---显示头信息1(第一行)
	 xs_head2   ---显示头信息2(第二行) "如 '----    ---  --' "
	 dy_head    ---打印标题
	 starty,startx,maxrow,maxcol 
		    ---屏幕显示区域的描述
	 insert_fun ---在光标所在行下插入一行的自定义函数指针,((int)0)表示空函数
		       入参: 插入字符串	
		       返回: 0成功,!0失败
	 delete_fun ---删除光标所在行的自定义函数指针,((int)0)表示空函数
		       入参: 光标所在行内容   
		       返回: 0成功,!0失败
	 update_fun ---修改光标所在行内容的自定义函数指针,对数据库进行操作后返回
		        ,((int)0)表示空函数
	               入参: char *             原光标所在行内容,
		             update_buff[2000]  存放修改后的行内容
		       返回:0成功  1失败  27取消
	 enter_fun  ---回车,对光标所在行进行操作的函数指针(入参:光标所在行内容)
			,((int)0)表示空函数
		       返回: 0成功,!0失败
返 回 值:0--正常  1--异常
*****************************************************************************/
int SHOW(char * file_name,char * xs_head1,char * xs_head2,char * dy_head,int starty,int startx,int maxrow,int maxcol,int (*insert_fun)(),int (*delete_fun)(),int (*update_fun)(),int (* enter_fun)() )
{	
	//int maxrow,maxcol      显示的最大行列个数
	//int starty,startx	 开始显示的起始行列座标 

	struct StructRow{   //存放文件一行内容的结构
		char * content;
		struct StructRow * next;
		struct StructRow * pre;
	};
	struct StructRow *p,*pq,*tmp,*mp,*start,*p_dy;
	int row,col;	         //结构中当前显示内容的起始位置	
	int maxlen=0;            //文件最长行的长度
	struct StructRow *p_HightLight; //高亮度行的指针
	int HightLight_y;		//高亮度行的相对行座标
	int i,ii,count,total;
	pid_t pid;
	char ch,*tmp1,TmpFileName[40];
	FILE * fp;	  //被显示的文件	
	FILE * fp1;	  //临时文件
	FILE * lp0_fp;
	char tmpbuff[2000],tmpbuff1[1000],dy_buff[1000],today[10],tj[1000];
	void repeat(int n,int starty,int startx);
	int get_sysdate(char *);
	//char * repeat_ch( char ch,int n);
	int ys=0,zys=0;

	double zje=0.00;	
	char str_je[12];

	//把文件 file_name 中的 Tab 字符换为7个空格
	if( (fp=fopen(file_name,"r"))==NULL){
		fprintf(stderr,"不能打开文件 %s",file_name);
		return(1);
	}
	if( (fp1=tmpfile())==NULL ){
		fprintf(stderr,"不能打开临时文件");
		return(1);
	}
	memset(tmpbuff,'\0',2000);
	strcpy(tmpbuff,"       ");
	while(!feof(fp)){
		ch=fgetc(fp);
		if(ch==9) //把 Tab 字符转换为7个空格  
			fwrite(tmpbuff,7,1,fp1);
		else
			fputc(ch,fp1);
	}
	fclose(fp);
	rewind(fp1);

	memset(tmpbuff,'\0',2000);


	//从文件中一行一行读入内容,置于双向链表中,p指向链表头,pq为移动指针

	//建立第一个链表项
	if((pq=(struct StructRow *)malloc(sizeof( struct StructRow)))==NULL)
		return(1);	
	fgets(tmpbuff,2000,fp1);	
	if(strlen(tmpbuff)>maxlen) //保存最长行的长度
		maxlen=strlen(tmpbuff);
	//给content赋值
	if((pq->content=(char *)malloc(strlen(tmpbuff)+1))==NULL)
		return(1);
	memset(pq->content,'\0',strlen(tmpbuff)+1);
	memcpy(pq->content,tmpbuff,strlen(tmpbuff));
	start=p=pq;

	while( !feof(fp1) ){ 	//从文件第二行开始读入
		memset(tmpbuff,'\0',2000);
		fgets(tmpbuff,2000,fp1);	

		//申请一结构项,链入链表	
		if( (pq->next=(struct StructRow *)malloc(sizeof( struct StructRow)))==NULL )
			return(1);	

		tmp=pq;
		//移动指针 pq	
		pq=pq->next;

		//结构项的pre指向前一项		
		pq->pre=tmp;

		//给结构项填入数据
		if(strlen(tmpbuff)>maxlen) //保存最长行的长度
			maxlen=strlen(tmpbuff);
		if((pq->content=(char *)malloc(strlen(tmpbuff)+1))==NULL)
			return(1);
		memset(pq->content,'\0',strlen(tmpbuff)+1);
		memcpy(pq->content,tmpbuff,strlen(tmpbuff));
	}
	fclose(fp1);
	pq->next=NULL;  //处理表头尾
	p->pre=NULL;    //链表建立完毕

	mp=pq=p;
	p_HightLight=p;
	HightLight_y=2;

	//显示
	row=0;
	col=0;

	//draw_box(starty-1,startx-2,starty+maxrow,startx+maxcol+2);

	//xxts( "光标键或PgU、PgD移动显示内容, p打印, ctrl+u修改  q返回");

	while(1){
		//清屏
		my_clear(starty,startx,maxrow,maxcol);

		mvprintw(22,2,"%s","〖提示信息〗                                                              ");
		mvprintw(22,14,"%s","光标键 PgU PgD移动显示内容, p打印, ctrl+u修改, 回车抹帐, q返回");

		//显示头信息
		memset(tmpbuff,'\0',2000);
		if(col<=strlen(xs_head1))
			my_strncpy(tmpbuff,xs_head1+col,maxcol);
		mvprintw(starty,startx,"%s",tmpbuff);

		memset(tmpbuff,'\0',2000);
		if(col<=strlen(xs_head2))
			my_strncpy(tmpbuff,xs_head2+col,maxcol);
		mvprintw(starty+1,startx,"%s",tmpbuff);

		//从结构中 row,col 处开始显示最多 maxrow 行 
		i=2;
		pq=mp;
		while((i<maxrow)&&(pq!=NULL)){
			memset(tmpbuff,'\0',2000);
			if(col<=strlen(pq->content)){  //显示一栏
				my_strncpy(tmpbuff,(pq->content)+col,maxcol);
				mvprintw(starty+i,startx,"%s",tmpbuff);
			}
			pq=pq->next;	
			i++;
		}

		//显示光带
		repeat(maxcol,starty+HightLight_y,startx); //反显 maxcol 个空格
		memset(tmpbuff,'\0',2000);
		if( strlen(p_HightLight->content)-1>col )
			my_strncpy(tmpbuff,(p_HightLight->content)+col,maxcol);
		standout();
		mvprintw(starty+HightLight_y,startx,"%s",tmpbuff);
		standend();

		refresh();
		ch=getchar();
		switch(ch){
			 case 71: //下翻 
				tmp=mp;ii=1;
				while((ii<=maxrow)&&(mp->next!=NULL)){
					mp=mp->next;
					ii++;
				}		
				if(ii<maxrow){
					beep();
					mp=tmp;
				}

				p_HightLight=mp;
				HightLight_y=2;

				break;
			case 73: //上翻
				tmp=mp;ii=1;
				while((ii<=maxrow)&&(mp->pre!=NULL)){
					mp=mp->pre;
					ii++;
				}		
				if(ii<maxrow){
					beep();
					mp=start;
				}

				p_HightLight=mp;
				HightLight_y=2;

				break;
			case 67: //右移
				if(col+1<maxlen)
					col=col+1;
				else
					beep();
				break;
			case 68://左移
				if(col-1>=0)
					col=col-1;
				else
					beep();
				break;
			case 65://下滚一行

				if( (HightLight_y>2) && (p_HightLight->pre!=NULL) ){
					HightLight_y--;
					p_HightLight=p_HightLight->pre;
				}
				else{
					if(mp->pre!=NULL){
						mp=mp->pre;
						if(p_HightLight->pre!=NULL)
							p_HightLight=p_HightLight->pre;
					}
					else
						beep();

				}

				break;
			case 66://上滚一行
				if( (HightLight_y<maxrow-1) && (p_HightLight->next!=NULL) ){
					p_HightLight=p_HightLight->next;
					HightLight_y++;
				}
				else{
					if(p_HightLight->next!=NULL){
						mp=mp->next;
						p_HightLight=p_HightLight->next;
					}
					else
						beep();

				}
				break;
			case 'p'://打印

				//打印内容格式打印入一个临时文件
				tmpnam(TmpFileName);

				lp0_fp=fopen(TmpFileName,"w");
				//lp0_fp=fopen("dy","w");

				p_dy=start; //指针复位
				fprintf(lp0_fp, "%s%s\n\n", 
repeat_ch(' ',(strlen(xs_head1)-strlen(dy_head))/2),dy_head );
				fprintf(lp0_fp,"%s\n",xs_head1);
				fprintf(lp0_fp,"%s\n",repeat_ch('-',strlen(xs_head1)));
				while(1){
					memset(dy_buff,0,1000);
					sprintf(dy_buff,"%s",p_dy->content);
					fprintf(lp0_fp,"%s",dy_buff);
					p_dy=p_dy->next;
					if(p_dy==NULL){ //链表尾
						{
						char today[9];
						fprintf(lp0_fp,"%s\n",repeat_ch('-',strlen(xs_head1)) );
						get_sysdate(today);
						fprintf(lp0_fp,"\n       打印日期: %s",today);
						}
						break;
					}
						
				} 	//end of while. 生成格式文件结束
				fclose(lp0_fp);
				

				//开始打印
				if( tty_type()==0 ) //终端	
				{
					system("echo ");
					sprintf(dy_buff,"cat %s",TmpFileName);
					system(dy_buff);
					printf("%c",12); //换页
					system("echo "); 
				}
				else{ //主机
				       sprintf(dy_buff,"cat %s  > /dev/lp0",TmpFileName);
				       system(dy_buff);
	       			       sprintf(dy_buff,"echo  > /dev/lp0");
	       			       system(dy_buff);
				} 

				break;

			case 21: //ctrl_u修改
				if( update_fun!=((int)0) ){
					char update_buff[2000];
					int ret=27;

					memset(update_buff,0,2000);

				        //进行'修改'操作
					ret=update_fun(p_HightLight->content,update_buff);
					if(ret==0 ){
						//修改链表内容
						p_HightLight->content=malloc(strlen(update_buff)+1);
						sprintf(p_HightLight->content,"%s",update_buff);
						//重绘光标所在行内容
						repeat(maxcol,starty+HightLight_y,startx); //反显 maxcol 个空格
						memset(tmpbuff,'\0',2000);
						if( strlen(p_HightLight->content)-1>col )
						my_strncpy(tmpbuff,(p_HightLight->content)+col,maxcol);
						standout();
						mvprintw(starty+HightLight_y,startx,"%s",tmpbuff);
						standend();
						touchwin(stdscr);
						wrefresh(stdscr);

						xxts_w("修改成功!!");
					}
					else if( ret==1 )
						xxts_w("修改失败!!");
				}
				break;
			case 1: //ctrl_a插入
				break;
			case 4: //ctrl_d删除  (还没完工)

				if( delete_fun!=((int)0) && p_HightLight!=NULL){
					struct StructRow *p_delete;
					int ret=27;

					ret=delete_fun(p_HightLight->content);
					if(ret==0 ){
					   //把当前结点从链表中删除
						 //表头
					   if(p_HightLight->pre==NULL){
					      p_delete=p_HightLight;

					      if(p_HightLight->next!=NULL){
						p_HightLight=p_HightLight->next;
						p_HightLight->pre=NULL;
						free(p_delete);
						mp=p_HightLight;
					      }
					      else {
						p_HightLight=mp=p=pq=NULL;
						free(p_delete);
					      }
					   }
						//表尾	
					   else if(p_HightLight->next==NULL){
					      p_delete=p_HightLight;

					      if(p_HightLight->pre!=NULL){
						p_HightLight=p_HightLight->pre;
						p_HightLight->next=NULL;
						free(p_delete);
					      }
					      else {
						p_HightLight=mp=p=pq=NULL;
						free(p_delete);
					      }
					   }
						//表中间
					   else{
					      p_delete=p_HightLight;
					      p_HightLight=p_HightLight->next;
					      (p_delete->pre)->next=p_HightLight;	
					       p_HightLight->pre=p_delete->next;
					       free(p_delete);
					   }
							
					//重绘屏幕内容

					   touchwin(stdscr);
					   wrefresh(stdscr);
					   xxts_w("删除成功!!");
					}
					else if( ret==1 )
						xxts_w("删除失败!!");
				}

				break;
			case 10: //回车
				if( enter_fun!=((int)0) ){
					touchwin(stdscr);
					wrefresh(stdscr);
				}
				break;
			case 'q'|'Q'://退出
				//释放链表空间
				p=pq=start;
				while( p!=NULL ){
					p=p->next;
					free(pq->content);
					free(pq);
					pq=p;
				}
				goto exit;
			
		} //end of switch
	} //end of while
exit:	
	return(0);
}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -