📄 proute.c
字号:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<signal.h>#include<curses.h>#include<malloc.h>#define MAXBUS 10000#define MAXROU 100000#define MAXSTA 3000#define ROUSTA 10#define ROWS 15#define ROW 5#define INROW 22#define MSGROW 23#define NITEM 3struct buses{ int no; int time; int owner; int rate; int gate; int model; int nseat;};struct rstation{ int bus; int sta; unsigned price; unsigned bprice;}rsta[MAXROU];int nrsta;int col[NITEM]={10,30,50};struct route{ int bus; int nsta; int p[ROUSTA];}rou[MAXBUS];int nrou;struct station{ int no; char code[5]; char name[10]; unsigned int howfar;}sta[MAXSTA];int nsta;char *tab[]={ "线路票价信息管理", "----------------------------------------" "---------------------------------------", "Q-退出 N-指定 B-班次 A-添加 M-修改 C-检查 D-删除 S-保存 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; int prou=0,prsta=0; int n; RP=getenv("ROOTPATH"); if(RP==NULL) return -1; init(); if((nsta=readsta())==-1) nsta=0; if((nrsta=readrsta())==-1) nrsta=0; if((nrou=readbus())==-1) quit=1; else { quit=0; idex(); } while(quit==0) { show(prou,prsta); 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(prsta<rou[prou].nsta-1) prsta++; break; case Up: if(prsta>0) prsta--; break; case PgUp: if(prou>0) prou--; prsta=0; break; case PgDn: if(prou<nrou-1) prou++; prsta=0; break; case Home: prou=0; prsta=0; break; case End: prou=nrou-1; prsta=0; break; case 'n': n=appoint(prou); if(n!=-1) prou=n; break; case 'b': n=findbus(prou); if(n!=-1) prou=n; break; case 'a': if(append(prou)!=-1) flag=1; break; case 'm': if(modify(prou,prsta)==0) flag=1; break; case 'c': if((n=check())!=-1) { prou=n; prsta=0; } break; case 'd': if(delete(prou,prsta)==0) { nrsta--; idex(); flag=1; if(prsta>=rou[prou].nsta&&prsta>0) prsta=rou[prou].nsta-1; } break; case 's': if(save()==0) flag=0; 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; } } erase(); refresh(); endwin();}init(){ int i; signal(SIGINT,SIG_IGN); initscr(); raw(); nonl(); noecho(); erase(); mvaddstr(1,(80-strlen(tab[0]))/2,tab[0]); for(i=0;i<NITEM;i++) mvaddstr(3,col[i],title[i]); mvaddstr(4,0,tab[1]); mvaddstr(20,0,tab[1]); mvaddstr(21,(80-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); return nsta; }}int readrsta(){ char fn[80]; char errs[128]; int fd; long size; int i,nrsta; sprintf(fn,"%s/bas/route.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>MAXROU*sizeof(struct rstation)) size=MAXROU*sizeof(struct rstation); lseek(fd,0L,0); read(fd,(char *)rsta,size); close(fd); nrsta=size/sizeof(struct rstation); return nrsta; }}int readbus(){ char fn[80]; char errs[128]; int fd; long size; struct buses bus; int nbus; sprintf(fn,"%s/bas/bus.dat",RP); fd=open(fn,O_RDONLY); if(fd==-1) { sprintf(errs,"文件%s打开失败!",fn); showmsg(errs); return -1; } else { size=sizeof(struct buses); for(nbus=0;nbus<MAXBUS;nbus++) if(read(fd,(char *)&bus,size)!=size) break; else rou[nbus].bus=bus.no; close(fd); return nbus; }}sort_rou(){ int i,j,k,n; k=nrou/2; while(k>0) { for(j=k;j<nrou;j++) { n=rou[j].bus; i=j-k; while(i>=0&&rou[i].bus>n) { rou[i+k].bus=rou[i].bus; i-=k; } rou[i+k].bus=n; } k/=2; }}int idex(){ int i,j,k,n; sort_rou(); for(i=0;i<nrou;i++) rou[i].nsta=0; for(i=0;i<nrsta;i++) { j=0; k=nrou-1; while(j<=k) { n=(j+k)/2; if(rsta[i].bus<rou[n].bus) k=n-1; else if(rsta[i].bus>rou[n].bus) j=n+1; else { rou[n].p[rou[n].nsta++]=i; break; } } }}int append(int prou){ int i,j,n,p; int st; unsigned price,bprice; i=0; while(1) { nrsta++; rou[prou].nsta++; p=rou[prou].nsta-1; if(nrsta>=MAXROU||rou[prou].nsta>=ROUSTA) { showmsg("空间已满, 不能再增加!"); break; } rou[prou].p[p]=nrsta-1; if(rou[prou].nsta>1) st=rsta[rou[prou].p[p-1]].sta+1; else st=0; price=0; bprice=0; n=rou[prou].p[p]; rsta[n].bus=rou[prou].bus; rsta[n].sta=st; rsta[n].price=price; rsta[n].bprice=bprice; show(prou,p); while(1) { if((n=get_n(p+ROW,col[0],"",&st,col[1]-col[0]))==-1) break; else { for(j=0;j<rou[prou].nsta;j++) if(st==rsta[rou[prou].p[j]].sta&&j!=p) break; if(j<rou[prou].nsta) showmsg("此站点有重复!"); else break; } } if(n==-1) break; else { for(j=0;j<nsta;j++) if(st==sta[j].no) break; if(j<nsta) mvaddstr(p+ROW,col[0],sta[j].name); else mvaddstr(p+ROW,col[0]," "); refresh(); } while(1) { if((n=get_n(p+ROW,col[1],"",&price,col[2]-col[1]))==-1) break; else if(price<0) showmsg("错误的票价!"); else break; } if(n==-1) break; else { move(p+ROW,col[1]); printw("%4d.%02d",price/100,price%100); refresh(); } bprice=price/2; while(1) { if((n=get_n(p+ROW,col[2],"",&bprice,79-col[2]))==-1) break; else { if(bprice<0||bprice>price) showmsg("错误的票价!"); else break; } } if(n==-1) break; else { move(p+ROW,col[2]); printw("%4d.%02d",bprice/100,bprice%100); refresh(); } n=rou[prou].p[p]; rsta[n].sta=st; rsta[n].price=price; rsta[n].bprice=bprice; i++; } nrsta--; rou[prou].nsta--; move(p+ROW,0); clrtoeol(); refresh(); if(i>0) return i; else return -1;}int modify(int prou,int prsta){ int i,j,n,p; int st; unsigned price,bprice; if(rou[prou].nsta<=0) return -1; p=rou[prou].p[prsta]; while(1) { st=rsta[p].sta; if((n=get_n(prsta+ROW,col[0],"",&st,col[1]-col[0]))==-1) break; else { for(j=0;j<rou[prou].nsta;j++) if(st==rsta[rou[prou].p[j]].sta&&j!=prsta) break; if(j<rou[prou].nsta) showmsg("此站点有重复!"); else break; } } for(j=0;j<nsta;j++) if(st==sta[j].no) break; if(j<nsta) mvaddstr(prsta+ROW,col[0],sta[j].name); else mvaddstr(prsta+ROW,col[0]," "); refresh(); if(n==-1) return -1; while(1) { price=rsta[p].price; if((n=get_n(prsta+ROW,col[1],"",&price,col[2]-col[1]))==-1) break; else { if(price<0) showmsg("错误的票价!"); else break; } } move(prsta+ROW,col[1]); printw("%4d.%02d",price/100,price%100); refresh(); if(n==-1) return n; while(1) { bprice=price/2; if((n=get_n(prsta+ROW,col[2],"",&bprice,79-col[2]))==-1) break; else if(bprice<0||bprice>price) showmsg("错误的票价!"); else break; } move(prsta+ROW,col[2]); printw("%4d.%02d",bprice/100,bprice%100); refresh(); if(n==-1) return -1; rsta[p].sta=st; rsta[p].price=price; rsta[p].bprice=bprice; return 0;}check(){ int i; char errs[128]; for(i=0;i<nrou&&rou[i].nsta>0;i++) ; if(i<nrou) { sprintf(errs,"%d 班次还没有站点!",rou[i].bus); showmsg(errs); return i; } else return -1;}int delete(int prou,int prsta){ int i,size; char c; if(rou[prou].nsta<=0) return -1; mvaddstr(INROW,30,"请确认删除?(y/n) "); refresh(); c=getkey(); if(c=='y'||c=='Y') { size=sizeof(struct rstation); for(i=rou[prou].p[prsta];i<nrsta-1;i++) memcpy((char *)(rsta+i),(char *)(rsta+i+1),size); for(i=prsta;i<rou[prou].nsta-1;i++) rou[prou].p[i]=rou[prou].p[i+1]; rou[prou].nsta--; return 0; } else return -1;}int save(){ char fn[80]; char errs[128]; int fd; long size,n; int i,j; sort_rou(); sprintf(fn,"%s/bas/route.dat",RP); fd=open(fn,O_WRONLY|O_TRUNC|O_CREAT); if(fd==-1) { sprintf(errs,"文件%s打开失败!",fn); showmsg(errs); return -1; } else { size=sizeof(struct rstation); for(i=0;i<nrou;i++) for(j=0;j<rou[i].nsta;j++) write(fd,(char *)(rsta+rou[i].p[j]),size); close(fd); chmod(fn,0666); return 0; }}int print(){ int i,j,k,n,start,end; char stas[10]; start=0; while(1) { clrin(); if(get_n(INROW,30,"起始序号: ",&start,10)==-1) return -1; if(start>=0&&start<nrou) break; } end=nrou-1; while(1) { clrin(); if(get_n(INROW,30,"结束序号: ",&end,10)==-1) return -1; if(end>=start&&end<nrou) break; } printf("%c{",0x1b); /* print initialize string */ printf("%30s\n%-10s%-10s%-10s%s\n%s\n",tab[0],"班次",title[0],title[1], title[2],tab[1]); for(i=start;i<=end;i++) { printf("%d\n",rou[i].bus); for(j=0;j<rou[i].nsta;j++) { n=rou[i].p[j]; for(k=0;k<nsta&&rsta[n].sta!=sta[k].no;k++) ; if(k<nsta) strcpy(stas,sta[k].name); else strcpy(stas,"(无)"); printf("%10c%-10s%4d.%02d %4d.%02d\n",' ',stas, rsta[n].price/100,rsta[n].price%100, rsta[n].bprice/100,rsta[n].bprice%100); } } 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(); }}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 prou,int prsta){ static int p=-1; static int pr=-1; static int n=-1; int i; move(2,65); clrtoeol(); if(nrou<=0) { mvaddstr(2,65,"0/0"); clrscr(); refresh(); return; } else mvprintw(2,65,"%d/%d",prou+1,nrou); move(3,65); clrtoeol(); mvprintw(3,65,"班次: %d",rou[prou].bus); if(rou[prou].nsta==0) { clrscr(); n=rou[prou].nsta; p=prou; pr=prsta; return; } if(pr!=-1) mvaddch(pr+ROW,col[0]-2,' '); if(p!=prou||n!=rou[prou].nsta) { p=prou; n=rou[p].nsta; for(i=0;i<ROWS&&i<n;i++) showone(ROW+i,rou[p].p[i]); for(;i<ROWS;i++) move(ROW+i,0), clrtoeol(); } pr=prsta; mvaddch(pr+ROW,col[0]-2,'>'); refresh();}showone(int row,int n){ int i; move(row,0), clrtoeol(); for(i=0;i<nsta&&sta[i].no!=rsta[n].sta;i++) ; if(i>=nsta) mvaddstr(row,col[0]," "); else mvaddstr(row,col[0],sta[i].name); move(row,col[1]); printw("%4d.%02d",rsta[n].price/100,rsta[n].price%100); move(row,col[2]); printw("%4d.%02d",rsta[n].bprice/100,rsta[n].bprice%100); refresh();}int appoint(int prou){ int n; n=prou+1; if(get_n(INROW,30,"请输入序号: ",&n,10)==-1) return -1; if(n<=nrou&&n>0) return n-1; else return -1;}int findbus(int prou){ int i,n; n=rou[prou].bus; if(get_n(INROW,30,"请输入班次号: ",&n,10)==-1) return -1; for(i=0;i<nrou&&n!=rou[i].bus;i++) ; if(i<nrou) return i; else return -1;}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 + -