📄 bookms.c
字号:
fputc('1', wfp); /*写入记录状态标志,1表示该记录有效*/
fwrite(cur_book_ptr, sizeof(struct BookNode), 1, wfp); /*用数据块写入方式 */
fclose(wfp); /*关闭文件*/
return;
}
/*****************************************************************/
/* add a new book to the pointer and save it to the data file */
void Add_New_Book() /*新添加一本书 */
{
char c;
int i, num, bookID, loop=0;
struct BookNode* new_node_ptr;
char str[BKNAMESZ], instr[BKNAMESZ];
char newBookID[BKIDSZ];
new_node_ptr =
(struct BookNode*)malloc(sizeof(struct BookNode));
if(new_node_ptr != NULL)
{
/*自动分配新书号 */
num = Alloc_NewID();
bookID = num;
/*将整形数字转换成五个字符长的字符串,左端补0 */
for(i=BKIDSZ-2; i>=0; i--)
{
newBookID[i] = num%10 + 48;
num = num/10;
}
newBookID[BKIDSZ-1] = '\0';
printf("new BookID: %s\n", newBookID);
strcpy(new_node_ptr->bkID, newBookID);
/*获得书名 */
printf("Please Input BookName(1~20 chars):\n");
gets(instr);
while(strlen(instr) > BKNAMESZ-1)
{
printf("Wrong input, it is too long!\n");
printf("Please Input BookName(1~20 chars):\n");
gets(instr);
}
sprintf(str, "%-20s", instr);
strcpy(new_node_ptr->bkName, str);
/*获得作者 */
printf("Please Input Book's writer(1~15 chars):\n");
gets(instr);
while(strlen(instr) > WRITERSZ-1)
{
printf("Wrong input, it is too long!\n");
printf("Please Input Book's writer(1~15 chars):\n");
gets(instr);
}
sprintf(str, "%-15s", instr);
strcpy(new_node_ptr->writer, str);
/*获得出版社 */
printf("Please Input Book's Press(1~15 chars):\n");
gets(instr);
while(strlen(instr) > PRESSSZ)
{
printf("Wrong input, it is too long!\n");
printf("Please Input Book's Press(1~15 chars):\n");
gets(instr);
}
sprintf(str, "%-15s", instr);
strcpy(new_node_ptr->Press, str);
/*获得出版时间 */
printf("Please Input Book's PubTime(like: 20020308):\n");
gets(instr);
loop = Assure_Time_True(instr); /*检测输入的时间是否合法 */
while(loop==-1)
{
printf("The time is wrong!\n");
printf("Please Input Book's PubTime(like: 20020308):\n");
gets(instr);
loop = Assure_Time_True(instr);
}
sprintf(str, "%-8s", instr);
strcpy(new_node_ptr->pubTime, str);
/*新加入的书默认状态为 在馆 */
new_node_ptr->curStatus = '0';
strcpy(new_node_ptr->rdID, "*****");
/*显示新书信息 */
Display_Record(new_node_ptr);
cur_book_ptr = new_node_ptr;
new_node_ptr = NULL;
/*询问是否添加该新书 */
printf("Add this book? (y/n):");
c = getch();
printf("%c\n", c);
if(c=='y'||c=='Y')
{
Save_cur_Book_Node(); /*将当前数目写到文件*/
free(cur_book_ptr); /*释放指针 */
cur_book_ptr = NULL;
if(bookID==book_record_Total) /*若记录是在最后插入的,则记录总数应该加1*/
{ /*新插入点为最后*/
book_record_Total++;
book_newID_Position = book_record_Total;
}
else
{
book_newID_Position = bookID+1;
book_delete_total--; /* 在中间插入一个新纪录,则中间的无效记录数目减一 */
}
Save_Book_Infor_Word(); /*保存信息字 */
printf("Adding Successful!\n");
}
else
{
printf("Adding Cancled!\n");
}
return;
}
else
{
printf("WARNING:Memory Error!\n");
return;
}
}
/***********************************************************/
/* to allocate a new ID to the new reader automatically */
int Alloc_NewID()
{
int num;
int result, i;
if(book_newID_Position==book_record_Total) /*前面没有空记录,从后面依次分配*/
num = book_newID_Position;
/*存在空记录,调用函数Search_Null_Record()搜索book_newID_Position后的*/
/*第一条空记录位置作为新数添加的位置 */
else
{
result = Search_Null_Record();
if(result < 0)
{
printf("Allocate newID Failed!\n");
return -1;
}
else
num = result;
}
return(num);
}
/**********************************************************************/
/*start from the book_newID_Position to search the ineffective record */
int Search_Null_Record()
{
char ch;
FILE *rfp;
int step;
if((rfp=fopen("BookData.txt","r")) == NULL)
{
printf("Open File Error!\n");
return -1;
}
printf("New_position:%d\n", book_newID_Position);
step = book_newID_Position * (BKRECSIZE+1);
step += (INFORSZ-1)*3;
fseek(rfp, step, 0);
ch = fgetc(rfp); /*读有效标志 */
while((ch=='1')&&(book_newID_Position<book_record_Total))
{
printf("sss\n");
book_newID_Position++;
fseek(rfp, BKRECSIZE, 1); /*跳过一条记录*/
ch = fgetc(rfp); /*读有效标志 */
}
fclose(rfp);
return(book_newID_Position);
}
/******************************************************/
/* 简单的检验输入的时间是否合法 */
int Assure_Time_True(char *time_str)
{
long num1, num2;
int loop;
int year, mon, day;
char date_str[TIMESZ], mon_str[3], day_str[3];
struct date *cur_date = (struct date*)malloc(sizeof(struct date));
if(strlen(time_str) != TIMESZ-1) /*时间错误(字符串长度不为8)*/
return -1;
num1 = atol(time_str); /*该函数自动取字符串前面的数字串而舍去后面的非数字串 */
if(num1>99999999 || num1<10000000)
return -1; /*时间错误(数字串长度不为8) */
year = num1 / 10000;
num2 = num1 % 10000;
mon = num2 / 100;
day = num2 % 100;
if(mon==0 || day==0)
return -1;
if(mon > 12)
return -1; /*时间错误(月份不正确) */
loop = Days_Per_Month(year, mon);
if(day > loop) return -1; /* 时间错误(比当前月份最大日期大)*/
getdate(cur_date);
sprintf(date_str, "%d", cur_date->da_year);
sprintf(mon_str, "%d", cur_date->da_mon);
sprintf(day_str, "%d", cur_date->da_day);
if(cur_date->da_mon < 10)
strcat(date_str, "0");
strcat(date_str, mon_str);
if(cur_date->da_day < 10)
strcat(date_str, "0");
strcat(date_str, day_str);
date_str[TIMESZ-1] = '\0';
if(strcmp(time_str, date_str) > 0)
return -1; /*时间错误(出版时间时间大于当前时间)*/
return 1;
}
int Days_Per_Month(int year, int mon)
{
int loop;
if((!(year%4)&&(year%100)) || !(year%400))
loop = 1; /*闰年 */
else
loop = 0; /*平年 */
switch(mon)
{
case(1):
case(3):
case(5):
case(7):
case(8):
case(10):
case(12):
return 31;
case(4):
case(6):
case(9):
case(11):
return 30;
case(2):
if(loop) return 29;
else return 28;
}
}
/**************************************************/
/* Search a book by different ways */
void Search_Book()
{
static char choice; /* 此处很重要,因为Switch_Search_Reader()中default中*/
/* 递归调用了该函数,设置为static则递归调用时使用同一个 */
/* choice 变量,即只做一次处理,而且可以正确退出*/
do
{
clrscr();
printf(" Searching Menu \n");
printf("1 - Search a book by a Book's ID\n");
printf("2 - Search a book by book's fullname\n");
printf("3 - Search a book by bookname's fisrt letter\n");
printf("4 - Search a book by author's fullname\n");
printf("5 - Search a book by Press's fullname\n");
printf("ESC - Return\n");
printf("Please input your choice:");
choice = getch();
printf("%c\n", choice);
if(choice!=27)
Switch_Search_Book(choice);
}while(choice!=27);
return;
}
/***********************************************/
void Switch_Search_Book(char c)
{
switch(c)
{
case('1'):
Search_By_BookID();
break;
case('2'):
Search_By_Book_Fullname();
break;
case('3'):
Search_By_First_Letter();
break;
case('4'):
Search_By_Writer();
break;
case('5'):
Search_By_Press();
break;
default:
printf("Invalid choice\n");
printf("Press any key to continue!\n");
getch();
Search_Book();
break;
}
return;
}
/***************************************************/
void Search_By_BookID()
{
int loop, num;
char instr[BKIDSZ];
num = Get_Book_ID();
if(num==-1) /* 操作取消 */
return;
Select_And_Display(num);
return;
}
/*************************************************************/
void Search_By_Book_Fullname()
{
int i, loop, match_total=0;
char ch;
char instr[BKNAMESZ], name_str[BKNAMESZ], temp_str[BKNAMESZ];
printf("Please Input Book'Fullname(1~20 chars):\n");
gets(instr);
while(strlen(instr) > BKNAMESZ-1)
{
printf("Wrong input, it is too long!\n");
printf("Please Input BookName(1~20 chars):\n");
gets(instr);
}
sprintf(name_str, "%-20s", instr);
clrscr();
for(i=0; i<book_record_Total; i++)
{
loop = Load_Book_Record(i);
if(loop != 1)
continue;
strcpy(temp_str, cur_book_ptr->bkName);
loop = strcmp(strlwr(temp_str), strlwr(name_str));
if(!loop)
{
match_total++;
if(match_total % PAGESIZE==1)
{
clrscr();
printf(" Number| Name | Writer | Press | Pub-Time |In-Lib\n");
printf("-------------------------------------------------------------------------------\n");
}
Display_Record(cur_book_ptr);
free(cur_book_ptr);
cur_book_ptr = NULL;
if(match_total % PAGESIZE==0)
{
printf("Press any key to the next page!\n");
getch();
}
}
}
printf("\nThere are %d matching records!\n", match_total);
if(match_total)
{
printf("Press P to continue, Press else key to return!\n");
ch = getch();
if(ch=='p'||ch=='P')
Search_By_BookID();
else
return;
}
else
{
printf("Press any key to continue!\n");
getch();
}
return;
}
/****************************************************************/
void Search_By_First_Letter()
{
int i, loop, match_total=0;
char ch, inch, tempch;
char instr[BKNAMESZ], name_str[BKNAMESZ], temp_str[BKNAMESZ];
printf("Please Input the first letter of the Book'name:\n");
inch = getch();
clrscr();
for(i=0; i<book_record_Total; i++)
{
loop = Load_Book_Record(i);
if(loop != 1)
continue;
tempch = cur_book_ptr->bkName[0];
if(tolower(inch)==tolower(tempch))
{
match_total++;
if(match_total % PAGESIZE==1)
{
clrscr();
printf(" Number| Name | Writer | Press | Pub-Time |In-Lib\n");
printf("-------------------------------------------------------------------------------\n");
}
Display_Record(cur_book_ptr);
free(cur_book_ptr);
cur_book_ptr = NULL;
if(match_total % PAGESIZE==0)
{
printf("Press any key to the next page!\n");
getch();
}
}
}
printf("\nThere are %d matching records!\n", match_total);
if(match_total)
{
printf("Press P to continue, Press else key to return!\n");
ch = getch();
if(ch=='p'||ch=='P')
Search_By_BookID();
else
return;
}
else
{
printf("Press any key to continue!\n");
getch();
}
return;
}
/******************************************************/
void Search_By_Writer()
{
int i, loop, match_total=0;
char ch, instr[WRITERSZ], writer_str[WRITERSZ], temp_str[WRITERSZ];
printf("Please Input Book'author's fullname(1~15 chars):\n");
gets(instr);
while(strlen(instr) > WRITERSZ-1)
{
printf("Wrong input, it is too long!\n");
printf("Please Input Book'author's fullname(1~15 chars):\n");
gets(instr);
}
sprintf(writer_str, "%-15s", instr);
clrscr();
for(i=0; i<book_record_Total; i++)
{
loop = Load_Book_Record(i);
if(loop != 1)
continue;
strcpy(temp_str, cur_book_ptr->writer);
loop = strcmp(strlwr(temp_str), strlwr(writer_str));
if(!loop)
{
match_total++;
if(match_total % PAGESIZE==1)
{
clrscr();
printf(" Number| Name | Writer | Press | Pub-Time |In-Lib\n");
printf("-------------------------------------------------------------------------------\n");
}
Display_Record(cur_book_ptr);
free(cur_book_ptr);
cur_book_ptr = NULL;
if(match_total % PAGESIZE==0)
{
printf("Press any key to the next page!\n");
getch();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -