#include #include #include "studlist03.h" int main() { char *filename="Student.txt"; FILE *fp; int i; Record r; int n; //char c; /* initialize */ head = make_1node( r, NULL ); /* input data from file */ if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "Cannot open %s!\n", filename); exit(1); } while (fscanf(fp, "%d %s %s %d", &r.id, r.surname, r.givenname, &r.age) != EOF) { if(insert(r) == NULL) printf("Error: %d appears twice in the file.\n", r.id); /* ここのメッセージは適当。なくてもよい */ } fclose(fp); listprint(); while (1) { /* rewind関数をコメントアウトすると,想定されていない入力があった場合に */ /* キーボードから入力された内容がバッファに残ったままになり,次のループ */ /* で意図しない動作を引き起こすことがある. */ /* 例えば以下のような例である. */ /* Chose operation で 0 を入力 */ /* Delete ID で A を入力(本来整数値のIDを入力すべきところに文字を入力 */ /* 以降,無限ループで以下の出力が繰り返される(Ctrl-Cで強制終了できる) */ /* Chose operation (1: Insert, 0: delete, ^D: Finish) -> Delete ID -> Error: Bad data format. */ /* なぜこのようなことが起きるのか,またなぜrewind関数で問題の発生を防げる */ /* のかは各自考えてみよ. */ /* rewind(stdin); */ printf("Choose operation (1: Insert, 0: Delete, ^D: Finish) -> "); if (scanf("%d", &n) == EOF) { printf("\n"); break; } switch (n) { case 1: /* insert list member */ printf("Insert new student data: (ID Surname Givenname Age) -> "); if (scanf("%d %s %s %d", &r.id, r.surname, r.givenname, &r.age) != 4) { printf("Error: Bad data format.\n"); break; } if (insert(r) == NULL) { printf("ID %d is already on the list!\n", r.id); } listprint(); break; case 0: /* delete list member */ printf("Delete ID -> "); if (scanf("%d", &i) != 1) { printf("Error: Bad data format.\n"); break; } if (delete(i) == NULL) { printf("ID %d is not found.\n", i); } listprint(); break; default: printf("Error: undefined command.\n"); break; } } return 0; } /* First, find item r, based on data ID */ /* If the ID is not found, insert r after the last node */ /* Return value: node(inserted), NULL(already exist) */ NodePointer insert(Record r) { NodePointer newnode, n; if (finditem(r.id) == NULL) { /* item not found and new node creation */ newnode = make_1node(r, NULL); /* trace nodes from head to tail */ for ( n=head; n->next!=NULL; n=n->next ); n->next = newnode; return newnode; } else return NULL; } /* find item by ID and delete that node if it exists */ /* return pos before(exist), NULL(not exist) */ NodePointer delete(int key) { NodePointer x, y; if ((x = finditem(key)) != NULL){ /* item found and node deletion */ y = x->next; x->next = y->next; /* free the memory */ if (y != NULL) { free(y); } } return x; } /* print all items in the list from head to tail */ void listprint(void) { NodePointer n; int count = 0; printf("Head - \n"); for(n = head->next; n != NULL; n = n->next){ printf(" %7d %-12s %-12s %d\n", n->data.id, n->data.surname, n->data.givenname, n->data.age); count++; } printf("%d nodes exist in the list.\n", count); printf("\n"); } /* find item id_data with given ID */ /* if found, return the address of the previous node. */ /* otherwise, return NULL */ NodePointer finditem(int sid) { NodePointer n; for(n = head; n->next != NULL; n = n->next) { if(n->next->data.id == sid) return n; } return NULL; } NodePointer make_1node(Record r, NodePointer p) { NodePointer n; if ((n = (NodePointer) malloc(sizeof(struct node)) ) == NULL) { printf("Error in memory allocation\n"); exit(8); } n->data = r; n->next = p; return n; }