📄 pcancel.c
字号:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<signal.h>#include<curses.h>#include<malloc.h>#include<time.h>#define MAXCNCL 1000#define ROWS 15#define ROW 5#define INROW 22#define MSGROW 23#define NITEM 3#define BEGINYEAR 1970#define DSEC 86400#define HSEC 3600#define MSEC 60struct cancels{ int bus; int date; int days;}can[MAXCNCL];int ncan;int order[MAXCNCL];int delf[MAXCNCL]; int col[NITEM]={20,35,55};struct buses{ int no; int time; int owner; int rate; int gate; int model; int nseat;}*bus;int nbus;struct time{ int second; /* 0--59 */ int minute; /* 0--59 */ int hour; /* 0--23 */ int mday; /* 1--31 */ int month; /* 1--12 */ int year; /* 1970-- */ int wday; /* 0--6(0=Sunday)*/ int yday; /* 1--365(366) */ long tseconds; /* seconds from 1970.1.1,0:0:0 */};char *tab[]={ "***** 撤 班 信 息 *****", "----------------------------------------" "---------------------------------------", "Q-退出 N-指定 A-添加 M-修改 D-删除 U-恢复 S-保存 R-排序 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 scan,pcan; int n; RP=getenv("ROOTPATH"); if(RP==NULL) return -1; init(); nbus=readbus(); if(nbus!=-1) { quit=0; ncan=readcan(); if(ncan!=-1) { sort(); for(n=0;n<ncan;n++) delf[n]=0; } else ncan=0; scan=0; pcan=0; } else quit=1; while(quit==0) { show(scan,pcan); move(21,41+strlen(tab[2])/2); refresh(); c=getkey(); clrin(); clrmsg(); if(c>='A'&&c<='Z') c=c-'A'+'a'; switch(c) { case -1: break; case Down: if(pcan<ncan-1) pcan++; if(pcan-scan>=ROWS) scan++; break; case Up: if(pcan>0) pcan--; if(pcan<scan&&scan>0) scan--; break; case PgUp: if(scan>=ROWS) scan-=ROWS; else scan=0; if(pcan>=ROWS) pcan-=ROWS; else pcan=0; break; case PgDn: if(scan<ncan-ROWS) scan+=ROWS; if(pcan<ncan-ROWS) pcan+=ROWS; else pcan=ncan-1; break; case Home: scan=0; pcan=0; break; case End: if(ncan%ROWS==0) scan=ncan-ROWS; else scan=ncan-ncan%ROWS; pcan=ncan-1; break; case 'n': n=appoint(pcan); if(n!=-1) { scan=n; pcan=n; } break; case 'a': if(append()==0) flag=1; if(ncan%ROWS==0) scan=ncan-ROWS; else scan=ncan-ncan%ROWS; pcan=ncan-1; break; case 'm': if(modify(scan,pcan)==0) flag=1; break; case 'd': if(delete(scan,pcan)==0) flag=1; break; case 'u': undelete(scan,pcan); break; case 's': if(save()==0) flag=0; break; case 'r': sort(); 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 readcan(){ char fn[80]; char msg[128]; int fd,i,date; long size,tn; struct time t; tn=time(0); gettime(tn,&t); date=t.year*10000+t.month*100+t.mday; sprintf(fn,"%s/bas/cancel.dat",RP); fd=open(fn,O_RDONLY); if(fd==-1) { sprintf(msg,"文件%s打开失败!",fn); showmsg(msg); return -1; } else { for(ncan=0;ncan<MAXCNCL;) { size=read(fd,(char *)(can+ncan),sizeof(struct cancels)); if(size!=sizeof(struct cancels)) break; for(i=0;i<nbus&&can[ncan].bus!=bus[i].no;i++) ; if(i<nbus&&getdays(can[ncan].date,date)<can[ncan].days) ncan++; } close(fd); return ncan/*size/sizeof(struct cancels)*/; }}int readbus(){ char fn[80]; char msg[128]; int fd; long size; sprintf(fn,"%s/bas/bus.dat",RP); fd=open(fn,O_RDONLY); if(fd==-1) { sprintf(msg,"文件%s打开失败!",fn); showmsg(msg); return -1; } else { size=lseek(fd,0L,2); bus=(struct buses *)malloc(size); if(bus==NULL) { showmsg("为班次数据分配内存出错!"); close(fd); return -1; } lseek(fd,0L,0); read(fd,(char *)bus,size); close(fd); return size/sizeof(struct buses); }}sort(){ int i,j,k,n; for(i=0;i<ncan;i++) order[i]=i; k=ncan/2; while(k>0) { for(j=k;j<ncan;j++) { n=order[j]; i=j-k; while(i>=0&&can[order[i]].bus>can[n].bus) { order[i+k]=order[i]; i-=k; } order[i+k]=n; } k/=2; }}int append(){ char ret=0; long tn; struct time t; int i; int busno,year,month,day,days; int n,scan,pcan; n=ncan; scan=n-n%ROWS; tn=time(0); gettime(tn,&t); while(ret==0) { ncan++; if(ncan>=MAXCNCL) { showmsg("空间已满, 不能再增加!"); break; } pcan=ncan-1; order[pcan]=pcan; if(nbus>ncan-1) busno=bus[pcan].no; else busno=0; year=t.year; month=t.month; day=t.mday; can[pcan].bus=busno; can[pcan].date=year*10000+month*100+day; can[pcan].days=31; if(pcan-scan>=ROWS) scan++; show(scan,pcan); while(ret==0) if(get_n(pcan-scan+ROW,col[0],"",&busno,col[1]-col[0])==-1) ret=1; else { for(i=0;i<nbus&&busno!=bus[i].no;i++) ; if(i>=nbus) { showmsg("不存在此班次!"); continue; } for(i=0;i<ncan;i++) if(busno==can[i].bus&&i!=pcan) break; if(i<ncan) showmsg("此班次编号有重复!"); else break; } if(ret==0) { mvprintw(pcan-scan+ROW,col[1],"%4d年%2d月%2d日", year,month,day); refresh(); if(get_n(pcan-scan+ROW,col[1],"",&year,5)==-1|| get_n(pcan-scan+ROW,col[1]+6,"",&month,3)==-1|| get_n(pcan-scan+ROW,col[1]+10,"",&day,3)==-1) ret=-1; } while(ret==0) { days=31; if(get_n(pcan-scan+ROW,col[2],"",&days,79-col[2])==-1) ret=1; else if(days<=0) showmsg("错误的有效天数!"); else break; } if(ret==0) { can[pcan].bus=busno; can[pcan].date=year*10000+month*100+day; can[pcan].days=days; } } ncan--; move(pcan-scan+ROW,0); clrtoeol(); refresh(); if(ncan!=n) return 0; else return -1;}int modify(int scan,int pcan){ long tn; struct time t; int i; int busno,year,month,day,days; busno=can[order[pcan]].bus; while(1) if(get_n(pcan-scan+ROW,col[0],"",&busno,col[1]-col[0])==-1) return -1; else { for(i=0;i<nbus&&busno!=bus[i].no;i++) ; if(i>=nbus) showmsg("不存在此班次!"); else{ for(i=0;i<ncan;i++) if(busno==can[i].bus&&order[pcan]!=i) break; if(i<ncan) showmsg("此班次编号有重复!"); else break; } } tn=time(0); gettime(tn,&t); year=t.year; month=t.month; day=t.mday; refresh(); if(get_n(pcan-scan+ROW,col[1],"",&year,5)==-1|| get_n(pcan-scan+ROW,col[1]+6,"",&month,3)==-1|| get_n(pcan-scan+ROW,col[1]+10,"",&day,3)==-1) return -1; mvprintw(pcan-scan+ROW,col[1],"%4d年%2d月%2d日",year,month,day); refresh(); days=can[order[pcan]].days; while(1) if(get_n(pcan-scan+ROW,col[2],"",&days,79-col[2])==-1) return -1; else if(days<=0) showmsg("错误的有效天数!"); else break; can[order[pcan]].bus=busno; can[order[pcan]].date=year*10000+month*100+day; can[order[pcan]].days=days; return 0;}int delete(int scan,int pcan){ if(ncan<=0) return -1; delf[order[pcan]]=1; mvaddch(ROW+pcan-scan,col[0]-1,'*'); refresh(); return 0;}int undelete(int scan,int pcan){ if(ncan<=0) return -1; if(delf[order[pcan]]) { delf[order[pcan]]=0; mvaddch(pcan-scan+ROW,col[0]-1,' '); refresh(); return 0; } else 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<ncan) break; } end=ncan-1; while(1) { clrin(); if(get_n(INROW,30,"结束序号: ",&end,10)==-1) return -1; if(end>=start&&end<ncan) break; } printf("%c{",0x1b); /* print initialize string */ printf("%30s\n%-10s%-16s%s\n%s\n",tab[0],title[0],title[1], title[2],tab[1]); for(i=start;i<=end;i++) { n=order[i]; printf("%-10d%d年%d月%d日 %d\n",can[n].bus, can[n].date/10000,can[n].date%10000/100, can[n].date%100,can[n].days); } printf("%c}",0x1b); /* print end string */ return 0;}int save(){ char fn[80]; char msg[128]; int fd; long size; int i; sprintf(fn,"%s/bas/cancel.dat",RP); fd=open(fn,O_WRONLY|O_TRUNC); if(fd==-1) { fd=open(fn,O_CREAT|O_WRONLY); if(fd==-1) { sprintf(msg,"文件%s打开失败!",fn); showmsg(msg); return -1; } } else { size=sizeof(struct cancels); for(i=0;i<ncan;i++) if(delf[i]==0) write(fd,(char *)(can+i),size); close(fd); chmod(fn,0666); 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 scan,int pcan){ static int n=-1; static int s=-1; static int p=-1; static int o[ROWS]; int i; move(2,70); clrtoeol(); if(ncan>0) mvprintw(3,70,"%d/%d",pcan+1,ncan); else { mvaddstr(3,70,"0/0"); clrscr(); refresh(); return; } mvaddch(p-s+ROW,col[0]-2,' '); if(p!=pcan) p=pcan; for(i=0;i<ROWS&&s+i<ncan&&o[i]==order[s+i];i++) ; if((n!=ncan&&(p-s)>=ROWS)||s!=scan||(i<ROWS&&s+i<ncan)) { n=ncan; s=scan; clrscr(); for(i=0;i<ROWS&&(s+i)<ncan;i++) { o[i]=order[s+i]; showone(ROW+i,o[i],s+i); } } else { move(p-s+ROW,0); clrtoeol(); showone(p-s+ROW,order[p],p); } mvaddch(p-s+ROW,col[0]-2,'>'); refresh();}showone(int row,int n,int nn){ int i; if(delf[n]) mvaddch(row,col[0]-1,'*'); mvprintw(row,col[0],"%d",can[n].bus); mvprintw(row,col[1],"%4d年%2d月%2d日",can[n].date/10000, can[n].date%10000/100,can[n].date%100); mvprintw(row,col[2],"%d",can[n].days);}int appoint(int pcan){ int n; char prompt[]="请输入序号: "; n=pcan+1; if(get_n(INROW,40-strlen(prompt)/2,prompt,&n,10)==-1) return -1; if(n-1<ncan) return n-1; 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");}clrmsg(){ move(MSGROW,0); clrtoeol(); refresh();}clrin(){ move(INROW,0); clrtoeol(); refresh();}int gettime(long tn,struct time *t){ int days,ydays; int TZ; char *tzs; int mdays[2][12]={31,28,31,30,31,30,31,31,30,31,30,31, 31,29,31,30,31,30,31,31,30,31,30,31}; int i; tzs=(char *)getenv("TZ"); if(tzs==NULL) TZ=0; else { for(;*tzs!='\0'&&*tzs!='+'&&*tzs!='-'&&(*tzs<'0'||*tzs>'9');tzs++) ; TZ=atoi(tzs); TZ=-TZ; } tn+=TZ*HSEC; days=tn/DSEC; t->tseconds=tn; t->wday=(days+4)%7; ydays=365; for(t->year=BEGINYEAR;days>=ydays;t->year++) { if(t->year%4==0) ydays=366; else ydays=365; days-=ydays; } t->yday=days; t->month=1; if(t->year%4==0) for(i=0;days>=mdays[1][i];i++) { days-=mdays[1][i]; t->month++; } else for(i=0;days>=mdays[0][i];i++) { days-=mdays[0][i]; t->month++; } t->mday=days+1; t->hour=tn%DSEC/HSEC; t->minute=tn%HSEC/MSEC; t->second=tn%MSEC; return 0;}int getdays(int date1,int date2){ int days; int mdays[2][12]={31,28,31,30,31,30,31,31,30,31,30,31, 31,29,31,30,31,30,31,31,30,31,30,31}; int i; int dd1,dd2; int y1,y2,m1,m2,d1,d2; if(date1>date2) dd1=date2, dd2=date1; else if(date1<date2) dd1=date1, dd2=date2; else return 0; y1=dd1/10000, y2=dd2/10000; m1=dd1%10000/100, m2=dd2%10000/100; d1=dd1%100, d2=dd2%100; days=0; for(i=y1+1;i<y2;i++) if(i%4==0) days+=366; else days+=365; if(y1==y2) for(i=m1;i<m2;i++) if(y1%4==0) days+=mdays[1][i-1]; else days+=mdays[0][i-1]; else { for(i=m1+1;i<=12;i++) if(y1%4==0) days+=mdays[1][i-1]; else days+=mdays[0][i-1]; for(i=1;i<m2;i++) if(y2%4==0) days+=mdays[1][i-1]; else days+=mdays[0][i-1]; } days-=d1; days+=d2; if(date1>date2) return -days; else return days;}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 + -