/* book.c 蔵書管理のための関数群 (C)2012 B11T3074C, B11T3011K - MIT License */ #include #include #include #include "util.h" #include "search.h" #include "book.h" // リストの先頭アドレス Bookdata *booklist_head = NULL; // キーボードから本のデータを入力 void input_data(Bookdata *target){ target->title = input_string("タイトル>", target->title); target->author = input_string("著者>", target->author); target->publisher = input_string("出版元>", target->publisher); target->year = input_string("発行年>", target->year); target->pages = input_string("ページ数>", target->pages); target->isbn = input_string("ISBN>", target->isbn); target->note = input_string("備考>", target->note); } // 本のデータを表示 void show_data(Bookdata *target){ printf("タイトル:\t%s\n", target->title); printf("著者:\t\t%s\n", target->author); printf("出版元:\t\t%s\n", target->publisher); printf("発行年:\t\t%s\n", target->year); printf("ページ数:\t%s\n", target->pages); printf("ISBN:\t\t%s\n", target->isbn); printf("備考:\t\t%s\n", target->note); } // 本のリストからデータを削除 void delete_data(Bookdata *target){ if(target->prev == NULL && target->next == NULL){ // 最後の1冊の場合 booklist_head = NULL; }else if(target->prev == NULL){ // 先頭の場合 booklist_head = target->next; (target->next)->prev = NULL; }else if(target->next == NULL){ // 末尾の場合 (target->prev)->next = NULL; }else{ (target->next)->prev = target->prev; (target->prev)->next = target->next; } free(target->title); // タイトル free(target->author); // 著者 free(target->publisher); // 出版元 free(target->year); // 発行年 free(target->pages); // ページ数 free(target->isbn); // ISBN free(target->note); // 備考 free(target); } // リストの末尾にnewdataを追加 void add_data(Bookdata *new_data){ Bookdata *tail; new_data->next = NULL; if(booklist_head == NULL) { // 最初の1冊の場合 booklist_head = new_data; new_data->prev = NULL; return; } // 末尾を検索 for(tail = booklist_head; tail->next != NULL; tail = tail->next); // 末尾の後ろにつなぐ tail->next = new_data; new_data->prev = tail; } // リストをすべて表示 void show_all(){ Bookdata *tail; puts("---"); for(tail = booklist_head; tail != NULL; tail = tail->next){ show_data(tail); puts("---"); } } // リストをCSVで保存 void savelist(char *filename){ FILE *fp; Bookdata *tail; // filenameが""ならば標準出力をオープンする if(filename[0] == '\0'){ fp = stdout; }else{ fp = fopen(filename, "w"); } fputs("title, author, publisher, year, pages, isbn, note\n", fp); for(tail = booklist_head; tail != NULL; tail = tail->next){ fputs(tail->title, fp); // タイトル fputs(", ", fp); fputs(tail->author, fp); // 著者 fputs(", ", fp); fputs(tail->publisher, fp); // 出版元 fputs(", ", fp); fputs(tail->year, fp); // 発行年 fputs(", ", fp); fputs(tail->pages, fp); // ページ数 fputs(", ", fp); fputs(tail->isbn, fp); // ISBN fputs(", ", fp); fputs(tail->note, fp); // 備考 fputs("\n", fp); } fclose(fp); } // リスト(CSVファイル)を開く int openlist(char *filename){ char buff[7][1024]; int i, j; FILE *fp; // filenameが空なら標準入力をオープンする if(filename[0] == '\0'){ fp = stdin; }else{ fp = fopen(filename, "r"); } if(fp == NULL){ fprintf(stderr, "\"%s\"が開けません\n", filename); return -1; } // 1行目はスルー fscanf(fp, "%[^\n]\n", buff[6]); while(EOF != fscanf(fp, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]\n", buff[0], buff[1], buff[2], buff[3], buff[4], buff[5], buff[6])){ Bookdata book; Bookdata *bp; for(i=0; i<7; i++){ // ","の後のスペースを削除 if(buff[i][0] == ' ') strcpy(buff[i], &buff[i][1]); } book.title = strdup(buff[0]); book.author = strdup(buff[1]); book.publisher = strdup(buff[2]); book.year = strdup(buff[3]); book.pages = strdup(buff[4]); book.isbn = strdup(buff[5]); book.note = strdup(buff[6]); bp = malloc(sizeof(Bookdata)); *bp = book; add_data(bp); } fclose(fp); return 0; } // bookを初期化 void init_data(Bookdata *book){ book->title = strdup(""); book->author = strdup(""); book->publisher = strdup(""); book->year = strdup(""); book->pages = strdup(""); book->isbn = strdup(""); book->note = strdup(""); } // 追加する void regist_data(){ Bookdata tmp; Bookdata *tail; init_data(&tmp); input_data(&tmp); tail = malloc(sizeof(Bookdata)); *tail = tmp; add_data(tail); } // 検索する void search(){ char buff[1024]; char pattern[1024]; Bookdata *tail; Bookdata *matches[1024]; int count; int i; printf("/"); input_line(pattern, 1024); count = 0; for(tail = booklist_head; tail != NULL; tail = tail->next){ if(smatch(pattern, tail->title) |smatch(pattern, tail->author) |smatch(pattern, tail->publisher) |smatch(pattern, tail->note)){ puts("---"); matches[count++] = tail; show_data(tail); } } if(count <= 0) return; // 見つからないので、戻る puts("---"); printf("削除[d] 戻る[x] "); input_line(buff, 1024); strtolower(buff); if(strcmp(buff, "d") == 0){ printf("削除します。よろしいですか? [y/N] "); if(select_y('N')){ for(i=0; i