239 lines
5.5 KiB
C
239 lines
5.5 KiB
C
/*
|
||
book.c
|
||
蔵書管理のための関数群
|
||
(C)2012 B11T3074C, B11T3011K - MIT License
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#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<count; i++){
|
||
delete_data(matches[i]);
|
||
}
|
||
}
|
||
return;
|
||
}else if(strcmp(buff, "x") == 0){
|
||
return;
|
||
}
|
||
}
|