📄 pstas.c
字号:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<signal.h>#include<curses.h>#include<malloc.h>#define MAXSTA 3000#define ROWS 15#define ROW 5#define INROW 22#define MSGROW 23#define NITEM 4struct station{ int no; char code[5]; char name[10]; unsigned int howfar;}sta[MAXSTA];int nsta;int order[MAXSTA];int delf[MAXSTA]; int col[NITEM]={10,25,40,60};char *tab[]={ "***** 站 点 信 息 *****", "----------------------------------------" "---------------------------------------", "Q-退出 N-指定 A-添加 M-修改 D-删除 U-恢复 S-保存 R-排序" " F-查询 P-打印"};char *title[]={"编号","代码","站名","里程"};enum Key{ /*NONE,*/Up,Down,Right,Left,Center,End,PgDn,Home, PgUp,Ins,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12};char *RP;main(int argc,char *argv[]){ char c; int flag=0; int quit=0; int ssta=0,psta=0; int n; RP=getenv("ROOTPATH"); if(RP==NULL) return -1; init(); nsta=readsta(); if(nsta==-1) nsta=0; while(quit==0) { show(ssta,psta); move(21,40+strlen(tab[2])/2); refresh(); c=getkey(); clrin(); clrerr(); if(c>='A'&&c<='Z') c=c-'A'+'a'; switch(c) { case -1: break; case Down: if(psta<nsta-1) psta++; if(psta-ssta>=ROWS) ssta++; break; case Up: if(psta>0) psta--; if(psta<ssta&&ssta>0) ssta--; break; case PgUp: if(ssta>=ROWS) ssta-=ROWS; else ssta=0; if(psta>=ROWS) psta-=ROWS; else psta=0; break; case PgDn: if(ssta<nsta-ROWS) ssta+=ROWS; if(psta<nsta-ROWS) psta+=ROWS; else psta=nsta-1; break; case Home: ssta=0; psta=0; break; case End: if(nsta%ROWS==0) ssta=nsta-ROWS; else ssta=nsta-nsta%ROWS; psta=nsta-1; break; case 'n': n=appoint(); if(n<nsta&&n>=0) { ssta=n; psta=n; } break; case 'a': if((n=append())!=-1) flag=1; if(nsta%ROWS==0) ssta=nsta-ROWS; else ssta=nsta-nsta%ROWS; psta=nsta-1; break; case 'm': if(modify(ssta,psta)==0) flag=1; break; case 'd': if(delete(psta)==0) { mvaddch(ROW+psta-ssta,col[0]-1,'*'); refresh(); flag=1; } break; case 'u': if(undelete(psta)==0) { mvaddch(ROW+psta-ssta,col[0]-1,' '); refresh(); } break; case 's': if(save()==0) flag=0; break; case 'r': sort(); break; case 'f': if((n=find(nsta))!=-1) { ssta=n; psta=n; } break; case 'p': print(); break; case 'q': if(flag==0) quit=1; else if(save()==0) quit=1; else if(yn("fail to save, quit(y/n)? ")==0) quit=1; break; default: printf("\07"); break; } } clear(); refresh(); endwin();}init(){ int i; signal(SIGINT,SIG_IGN); initscr(); raw(); nonl(); noecho(); clear(); mvaddstr(ROW-4,40-strlen(tab[0])/2,tab[0]); for(i=0;i<NITEM;i++) mvaddstr(ROW-2,col[i],title[i]); mvaddstr(ROW-1,0,tab[1]); mvaddstr(ROW+ROWS,0,tab[1]); mvaddstr(ROW+ROWS+1,40-strlen(tab[2])/2,tab[2]); refresh();}int readsta(){ char fn[80]; char errs[128]; int fd; long size; int i,nsta; sprintf(fn,"%s/bas/stas.dat",RP); fd=open(fn,O_RDONLY); if(fd==-1) { sprintf(errs,"文件%s打开失败!",fn); showmsg(errs); return 0; } else { size=lseek(fd,0L,2); if(size>MAXSTA*sizeof(struct station)) size=MAXSTA*sizeof(struct station); lseek(fd,0L,0); read(fd,(char *)sta,size); close(fd); nsta=size/sizeof(struct station); for(i=0;i<nsta;i++) order[i]=i, delf[i]=0; return nsta; }}sort(){ int i,j,k,n; k=nsta/2; while(k>0) { for(j=k;j<nsta;j++) { n=order[j]; i=j-k; while(i>=0&&strcmp(sta[order[i]].code,sta[n].code)>0) { order[i+k]=order[i]; i-=k; } order[i+k]=n; } k/=2; }}int append(){ int i,j,n; int no,howfar; char code[5],name[10]; int ssta,psta; ssta=nsta-nsta%ROWS; i=0; while(1) { nsta++; if(nsta>=MAXSTA) { showmsg("空间已满, 不能再增加!"); break; } psta=nsta-1; order[psta]=psta; if(nsta>1) no=sta[order[psta-1]].no+1; else no=0; code[0]='\0'; name[0]='\0'; howfar=0; n=order[psta]; sta[n].no=no; sta[n].code[0]='\0'; sta[n].name[0]='\0'; sta[n].howfar=howfar; if(psta-ssta>=ROWS) ssta++; show(ssta,psta); while(1) { if((n=get_n(psta-ssta+ROW,col[0],"",&no,col[1]-col[0]))==-1) break; else { for(j=0;j<nsta;j++) if(no==sta[j].no&&order[psta]!=j) break; if(j<nsta) showmsg("此站点编号有重复!"); else break; } } if(n==-1) break; while(1) { if((n=get_s(psta-ssta+ROW,col[1],"",code,col[2]-col[1]))==-1) break; else { for(j=0;j<nsta;j++) if(strcmp(code,sta[j].code)==0) break; if(j<nsta) showmsg("此站点代码有重复!"); else break; } } if(n==-1) break; if(get_s(psta-ssta+ROW,col[2],"",name,col[3]-col[2])==-1) break; if(get_n(psta-ssta+ROW,col[3],"",&howfar,79-col[3])==-1) break; n=order[psta]; sta[n].no=no; strcpy(sta[n].code,code); strcpy(sta[n].name,name); sta[n].howfar=howfar; i++; } nsta--; move(psta-ssta+ROW,0); clrtoeol(); refresh(); if(i>0) return i; else return -1;}int modify(int ssta,int psta){ int i,j,n; int no,howfar; char code[5],name[10]; no=sta[order[psta]].no; while(1) { if((n=get_n(psta-ssta+ROW,col[0],"",&no,col[1]-col[0]))==-1) break; else { for(j=0;j<nsta;j++) if(no==sta[j].no&&order[psta]!=j) break; if(j<nsta) showmsg("此站点编号有重复!"); else break; } } if(n==-1) return -1; strcpy(code,sta[order[psta]].code); while(1) { if(get_s(psta-ssta+ROW,col[1],"",code,col[2]-col[1])==-1) return -1; for(j=0;j<nsta;j++) if(strcmp(code,sta[j].code)==0&&j!=order[psta]) break; if(j<nsta) showmsg("此站点代码有重复!"); else break; } strcpy(name,sta[order[psta]].name); if(get_s(psta-ssta+ROW,col[2],"",name,col[3]-col[2])==-1) return -1; howfar=sta[order[psta]].howfar; if(get_n(psta-ssta+ROW,col[3],"",&howfar,79-col[3])==-1) return -1; sta[order[psta]].no=no; strcpy(sta[order[psta]].code,code); strcpy(sta[order[psta]].name,name); sta[order[psta]].howfar=howfar; return 0;}int delete(int psta){ delf[order[psta]]=1; return 0;}int undelete(int psta){ if(delf[order[psta]]) { delf[order[psta]]=0; return 0; } else return -1;}int save(){ char fn[80]; char errs[128]; int fd; long size; int i; sprintf(fn,"%s/bas/stas.dat",RP); fd=open(fn,O_WRONLY|O_TRUNC); if(fd==-1) { fd=open(fn,O_CREAT|O_WRONLY); if(fd==-1) { sprintf(errs,"文件%s打开失败!",fn); showmsg(errs); return -1; } } sort(); size=sizeof(struct station); for(i=0;i<nsta;i++) if(delf[i]==0) write(fd,(char *)(sta+i),size); close(fd); return 0;}int find(nsta){ int i; char s[80]=""; if(get_s(INROW,30,"待查站点编码: ",s,10)==-1) return -1; for(i=0;i<nsta;i++) if(strcmp(s,sta[order[i]].code)==0) break; if(i<nsta) return i; else { showmsg("所查询的站点不存在!"); return -1; }}int print(){ int i,n,start,end; start=0; while(1) { clrin(); if(get_n(INROW,30,"起始序号: ",&start,10)==-1) return -1; if(start>=0&&start<nsta) break; } end=nsta-1; while(1) { clrin(); if(get_n(INROW,30,"结束序号: ",&end,10)==-1) return -1; if(end>=start&&end<nsta) break; } printf("%c{",0x1b); /* print initialize string */ printf("%30s\n%-10s%-10s%-15s%s\n%s\n",tab[0],title[0],title[1], title[2],title[3],tab[1]); for(i=start;i<=end;i++) { n=order[i]; printf("%-10d%-10s%-15s%d\n",sta[n].no,sta[n].code, sta[n].name,sta[n].howfar); } printf("%c}",0x1b); /* print end string */ return 0;}int get_n(int y,int x,char *prompt,int *n,int b){ char c,s[80],ss[80]; int i; sprintf(s,"%d",*n); for(i=0;i<b-1;i++) ss[i]=' '; ss[b-1]='\0'; mvaddstr(y,x,prompt); x+=strlen(prompt); mvaddstr(y,x,ss); mvaddstr(y,x,s); refresh(); i=0; while(1) { move(y,x+i); refresh(); if(i>=b-1) c=0x0d; else c=getkey(); switch(c) { case -1: continue; case 0x1b: /* <ESC> pressed */ return -1; case 0x0d: /* <ENTER> pressed */ if(i) { ss[i]='\0'; *n=atoi(ss); } return 0; case 0x08: /* <BS> pressed */ if(i<=0) continue; else { ss[--i]=' '; ss[i]='\0'; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ss[i++]=c; break; default: printf("\7\7"); break; } mvaddstr(y,x,ss); refresh(); }}int get_s(int y,int x,char prompt[],char s[],int n) /* x,y location of cursor; s the string */ /* n length of s; */{ char c,ss[128]; int i; for(i=0;i<n-1;i++) ss[i]=' '; ss[n-1]='\0'; mvaddstr(y,x,prompt); x+=strlen(prompt); mvaddstr(y,x,ss); mvaddstr(y,x,s); refresh(); i=0; while(1) { move(y,x+i); refresh(); if(i>=n-1) c=0x0d; else c=getkey(); switch(c) { case -1: continue; case 0x1b: /* <ESC> pressed */ return -1; case 0x0d: /* <ENTER> pressed */ if(i) { ss[i]='\0'; strcpy(s,ss); } return 0; case 0x08: /* <BS> pressed */ if(i<=0) continue; else ss[--i]=' '; break; default: ss[i++]=c; break; } mvaddstr(y,x,ss); refresh(); }}getkey(){ char c,key; char keys[]={Up,Down,Right,Left,NONE,End,PgDn,Home, PgUp,NONE,NONE,Ins}; void timeint(); sigset(SIGALRM,timeint); key=getch(); refresh(); if(key==0x1b) { alarm(1); if(getch()!=-1) { c=getch(); refresh(); key=keys[c-'A']; } } sigignore(SIGALRM); return key;}void timeint(){}show(int ssta,int psta){ static int s=-1; static int p=-1; static int o[ROWS]; int i; move(2,70); clrtoeol(); if(nsta<=0) { mvaddstr(2,70,"0/0"); clrscr(); refresh(); return; } else mvprintw(2,70,"%d/%d",psta+1,nsta); if(nsta==0) return; mvaddch(p-s+ROW,col[0]-2,' '); if(p!=psta) p=psta; if(s==ssta) for(i=0;i<ROWS&&s+i<nsta&&o[i]==order[s+i];i++) ; if(s!=ssta||(i<ROWS&&s+i<nsta)) { s=ssta; for(i=0;i<ROWS&&(s+i)<nsta;i++) { o[i]=order[s+i]; showone(ROW+i,o[i]); } for(;i<ROWS;i++) move(ROW+i,0), clrtoeol(); } mvaddch(p-s+ROW,col[0]-2,'>'); refresh();}showone(int row,int n,int nn){ int i; move(row,0), clrtoeol(); if(delf[n]) mvaddch(row,col[0]-1,'*'); mvprintw(row,col[0],"%d",sta[n].no); mvaddstr(row,col[1],sta[n].code); mvaddstr(row,col[2],sta[n].name); mvprintw(row,col[3],"%d",sta[n].howfar);}int appoint(){ int n; n=-1; if(get_n(INROW,30,"请输入序号: ",&n,10)==-1) return -1; return n;}clrscr(){ int i; for(i=0;i<ROWS;i++) { move(ROW+i,0); clrtoeol(); } refresh();}showmsg(char s[]){ move(MSGROW,0); clrtoeol(); mvaddstr(MSGROW,(80-strlen(s))/2,s); refresh(); printf("\7\7");}clrerr(){ move(MSGROW,0); clrtoeol(); refresh();}clrin(){ move(INROW,0); clrtoeol(); refresh();}int yn(char *p){ char c; do{ move(INROW,0); clrtoeol(); mvprintw(INROW,40-strlen(p)/2,p); move(INROW,41+strlen(p)/2); refresh(); c=getkey(); }while(c!='y'&&c!='Y'&&c!='n'&&c!='N'); if(c>='A'&&c<='Z') c=c-'A'+'a'; if(c=='y') return 0; else return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -