273 lines
6.5 KiB
C
273 lines
6.5 KiB
C
/* sList.c */
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
/* 定義一指向 FILE 的指標 */
|
||
FILE *fptr;
|
||
|
||
/* 函式的原型宣告 */
|
||
void init_f(void);
|
||
void insertStudent(int id, char* name, double score);
|
||
void readFromFile(const char* filename);
|
||
void saveToFile(const char* filename);
|
||
void insert(void);
|
||
void del(void);
|
||
void modify(void);
|
||
void display(void);
|
||
|
||
// 定義學生節點結構
|
||
typedef struct Student {
|
||
long int id;
|
||
char name[10];
|
||
double score;
|
||
struct Student *rlink;
|
||
struct Student *llink;
|
||
} Student;
|
||
Student *head, *pNode ,*tail, *current, *prev, *temp ;
|
||
|
||
//設一個 head,將左右鏈結皆指向本身
|
||
void init_f() {
|
||
head = (Student *) malloc(sizeof(Student));
|
||
tail = (Student *) malloc(sizeof(Student));
|
||
|
||
// 初始化 head 和 tail
|
||
head->llink = NULL;
|
||
head->rlink = tail;
|
||
|
||
tail->llink = head;
|
||
tail->rlink = NULL;
|
||
}
|
||
|
||
// 在尾部插入新學生節點
|
||
void insertStudent(int id, char* name, double score) {
|
||
|
||
Student* newNode = (Student*)malloc(sizeof(Student));
|
||
|
||
|
||
newNode->id = id;
|
||
strcpy(newNode->name, name);
|
||
newNode->name[9] = '\0';
|
||
newNode->score = score;
|
||
|
||
// 插入到尾部之前
|
||
newNode->rlink = tail;
|
||
newNode->llink = tail->llink;
|
||
tail->llink->rlink = newNode;
|
||
tail->llink = newNode;
|
||
}
|
||
|
||
// 讀檔
|
||
void readFromFile(const char* filename) {
|
||
char line[100];
|
||
FILE* fptr = fopen(filename, "r");
|
||
if (fptr == NULL) {
|
||
printf("無法打開檔案 %s\n", filename);
|
||
return;
|
||
}
|
||
|
||
long int id;
|
||
char name[10];
|
||
double score;
|
||
while(fgets(line ,sizeof(line) ,fptr)!=NULL){
|
||
if(sscanf(line,"%ld\t%9s\t%lf", &id, name, &score) == 3){
|
||
insertStudent(id, name, score);
|
||
}
|
||
}
|
||
fclose(fptr);
|
||
printf("顯示檔案資料\n");
|
||
}
|
||
|
||
// 存檔
|
||
void saveToFile(const char* filename ) {
|
||
FILE* fptr = fopen(filename, "w");
|
||
if (fptr == NULL) {
|
||
printf("無法打開檔案 %s 進行寫入\n", filename);
|
||
return;
|
||
}
|
||
Student* current = head->rlink;
|
||
while (current != tail ) {
|
||
fprintf(fptr, "%ld\t%s\t%.lf\n", current->id, current->name, current->score);
|
||
current = current->rlink;
|
||
}
|
||
|
||
fclose(fptr);
|
||
printf("資料已成功\儲存到 %s\n", filename);
|
||
}
|
||
|
||
//顯示串列資料
|
||
void printStudentList() {
|
||
|
||
Student* current = head->rlink;
|
||
printf("\n*******************************");
|
||
|
||
if (current != NULL) {
|
||
printf("\n%6s %10s %8s\n", "ID", "Name", "Score");
|
||
printf("-------------------------------\n");
|
||
while (current != tail) {
|
||
printf("%6ld %10s %8.1f\n", current->id,current->name, current->score);
|
||
/* 將指標移到下一個節點 */
|
||
current = current->rlink;
|
||
}
|
||
}
|
||
/* 若是空的,則輸出鏈結串列無資料 */
|
||
else {
|
||
printf("\n鏈結串列無資料\n");
|
||
}
|
||
printf("*******************************\n\n");
|
||
}
|
||
|
||
int main(){
|
||
init_f();
|
||
readFromFile("list.txt");
|
||
printStudentList();
|
||
/* 利用一選單讓使用選擇功能項目 */
|
||
int choice;
|
||
do {
|
||
printf("************************\n");
|
||
printf("鏈結串列的運作選單\n");
|
||
printf("1. 加入一節點\n");
|
||
printf("2. 刪除一節點\n");
|
||
printf("3. 修改一節點\n");
|
||
printf("4. 顯示所有節點\n");
|
||
printf("5. 結束\n");
|
||
printf("請選擇: ");
|
||
scanf("%d", &choice);
|
||
switch (choice) {
|
||
case 1:
|
||
insert();
|
||
break;
|
||
case 2:
|
||
del();
|
||
break;
|
||
case 3:
|
||
modify();
|
||
break;
|
||
case 4:
|
||
printStudentList();
|
||
break;
|
||
case 5:
|
||
printf("\n程式結束\n");
|
||
saveToFile("list.txt");
|
||
exit(0);
|
||
default:
|
||
printf("輸入號碼不正確,請重新輸入\n");
|
||
}
|
||
printf("\n");
|
||
} while(choice != 5);
|
||
getchar();
|
||
return 0;
|
||
}
|
||
|
||
/* 按照分數由大至小加入一節點於鏈結串列 */
|
||
void insert()
|
||
{
|
||
/* 利用 malloc() 函式配置記憶體*/
|
||
Student* newNode = (Student*)malloc(sizeof(Student));
|
||
|
||
printf("\n請輸入ID: ");
|
||
scanf("%ld", &newNode->id);
|
||
printf("請輸入姓名: ");
|
||
scanf("%s", newNode->name);
|
||
printf("請輸入分數: ");
|
||
scanf("%lf", &newNode->score);
|
||
|
||
/* 加入一節點於鏈結串列 */
|
||
current = head->rlink;
|
||
prev = head;
|
||
|
||
// 插入到尾部之前
|
||
newNode->rlink = tail;
|
||
newNode->llink = tail->llink;
|
||
tail->llink->rlink = newNode;
|
||
tail->llink = newNode;
|
||
}
|
||
|
||
/* 刪除某一節點*/
|
||
void del()
|
||
{
|
||
long int deleteID;
|
||
/* 將 current 指標指向 head 的下一個節點 */
|
||
current = head->rlink;
|
||
prev = head;
|
||
/* 先判斷鏈結串列是否為空 */
|
||
if (current != NULL) {
|
||
/* 若不是空的,則找尋欲刪除的節點 */
|
||
printf("\n請輸入欲刪除的 ID: ");
|
||
scanf("%ld", &deleteID);
|
||
/* 找尋欲刪除的節點 */
|
||
while ((current != tail) && (current->id != deleteID)) {
|
||
prev = current;
|
||
current = current->rlink;
|
||
}
|
||
/* 若找到,則將它刪除 */
|
||
if (current != tail) {
|
||
current->rlink->llink = prev;
|
||
prev->rlink = current->rlink;
|
||
printf("ID: %ld 已刪除\n", current->id);
|
||
|
||
free(current);
|
||
}
|
||
/* 若沒有找到,則輸出找不到欲刪除節點的訊息*/
|
||
else {
|
||
printf("\n找不到欲刪除的節點\n");
|
||
}
|
||
}
|
||
/* 若是空的,則輸出鏈結串列是空的訊息 */
|
||
else {
|
||
printf("鏈結串列是空的\n");
|
||
}
|
||
}
|
||
|
||
/* 修改某一節點 */
|
||
void modify()
|
||
{
|
||
Student *temp;
|
||
long int modifyID;
|
||
double modifyScore;
|
||
int flag = 0;
|
||
printf("\n請輸入欲修改節點的 ID: ");
|
||
scanf("%ld", &modifyID);
|
||
current = head->rlink;
|
||
prev = head;
|
||
|
||
/* 找尋欲修改的節點 */
|
||
while (current != tail) {
|
||
if (current->id == modifyID) {
|
||
printf("目前欲修改節點的資料如下:\n");
|
||
printf("%6ld %10s %8.1f\n\n", current->id,current->name, current->score);
|
||
printf("請輸入欲修改的分數: ");
|
||
scanf("%lf", &modifyScore);
|
||
current->score = modifyScore;
|
||
flag = 1;
|
||
break;
|
||
}
|
||
else {
|
||
prev = current;
|
||
current = current->rlink;
|
||
}
|
||
}
|
||
/* 判斷是否有找到欲修改的節點 */
|
||
if (flag != 0) {
|
||
/* 將 current 的節點指定給 temp */
|
||
// temp = current;
|
||
// prev->rlink = current->rlink;
|
||
/* 將 temp 節點加入於鏈結串列 */
|
||
// current = head->rlink;
|
||
// prev = head;
|
||
// while ((current != tail) && (temp->score < current->score)) {
|
||
// prev = current;
|
||
// current = current->rlink;
|
||
// }
|
||
// prev->rlink = temp;
|
||
// temp->rlink = current;
|
||
}
|
||
else {
|
||
printf("找不到欲修改的節點\n");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|