國立屏東大學 資訊工程系 程式設計(二)
本次Turnin作業包含多個程式題,建議同學可以為這次作業先建立一個資料夾hw5,然後在該資料夾內再為每一題建立一個子資料夾,用以進行每一題的作答以及上傳。每一題的子資料夾名稱已寫於題目前方,請務必依照題目的規定建立子資料夾,例如第1題為p1、第2題為p2,餘依此類推。當我們完成某一個題目的作答後,就可以使用turnin指令將該題的答案上傳。以第1題為例,當我們在p1子資料夾裡完成作答後,就可以回到hw5資料夾,使用以下指令將其上傳:
[user@ws hw5]$ turnin▴c.hw5▴p1↵
當然,你也可以等到所有題目都完成後,再回到hw5資料夾,使用以下指令將所有題目都加以上傳:
[user@ws hw5]$ turnin▴c.hw5▴.↵
本文使用▴及↵代表空白字元與Enter換行字元,並且將使用者輸入的部份使用灰階方式顯示。
另外,題目的執行結果中,如果出現(、)、:、;、.與,等符號,皆為英文半形!
當你完成此次作業的繳交後,可以使用turnin指令的-ls參數,查看已繳交的結果。若已經正確地依要求繳交此次作業,那麼你將可以看到類似以下的查詢結果:
[user@ws hw5]$ turnin -ls c.hw5 .: total 20 drwxrwx---. 2 turninman 1669401585 4096 Mar 5 20:57 p1 drwxrwx---. 2 turninman 1669401585 4096 Mar 5 20:57 p2 ./p1: total 8 -rw-rw----. 1 turninman 1669401585 4 Mar 5 20:57 StringBox.c -rw-rw----. 1 turninman 1669401585 4 Mar 5 20:57 StringBox.h ./p2: total 8 -rw-rw----. 1 turninman 1669401585 4 Mar 5 20:57 SouvenirShop.c -rw-rw----. 1 turninman 1669401585 4 Mar 5 20:57 SouvenirShop.h [user@ws hw5]$
【注意:以上的執行結果僅供參考,包含檔案上傳的日期、時間、大小等皆會依實際情況有所不同,請自行仔細檢查是否有正確繳交。】
若是發現自己繳交錯誤的同學,也可以使用以下的指令,將此次作業所有已上傳的檔案與資料夾全部清空:
[user@ws hw5]$ turnin▴-rm▴c.hw5↵
請參考如下 Main.c 的程式碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "StringBox.h"
#define true 1
#define false 0
int help_prompt(){
printf("You can use the following commands:\n");
printf("--------------------------------------------\n");
printf("[insert] or [add] - Insert a new string\n");
printf("[list] or [ls] - List all strings\n");
printf("[delete] or [rm] - Delete a string\n");
printf("[sort] - Sort the strings\n");
printf("[status] - Show the current number of strings\n");
printf("[help] - Show this help message\n");
printf("[quit] or [exit] - Exit the String Box\n");
return 0;
}
int welcome_prompt(){
printf("Welcome to the String Box!\n");
help_prompt();
return 0;
}
int main(){
int quit = false;
int index = 0;
char **strbox = NULL;
int str_quantity = 0;
int strbox_size = 0;
int unreleased_count = 0;
char *temp = NULL;
char *cmd = malloc(10*sizeof(char));
welcome_prompt();
while(!quit){
printf("--------------------------------------------\n");
printf(">> "); // input prompt
scanf(" %10[^\n]", cmd); // get command within 10 char
if(!strcmp(cmd, "insert") || !strcmp(cmd, "add")){
temp = get_a_string();
str_quantity = insertion(&strbox, temp, str_quantity);
printf("The string [%s] has been stored.\n", temp);
} else if(!strcmp(cmd, "list") || !strcmp(cmd, "ls")){
list_all(strbox, str_quantity);
} else if(!strcmp(cmd, "delete") || !strcmp(cmd, "rm")){
if(str_quantity == 0){
printf("The String Box is empty. Nothing to delete.\n");
continue;
}
list_all(strbox, str_quantity);
printf("Please enter the index of the string to delete(\'0\' for cancellation): ");
scanf(" %d", &index);
if(index == 0){
printf("Deletion cancelled.\n");
continue;
} else if (index > str_quantity || index < 0){
printf("Invalid index. Operation failed.\n");
continue;
} else {
deletion(&strbox, &str_quantity, index);
}
} else if(!strcmp(cmd, "sort")){
if(str_quantity == 0){
printf("The String Box is empty. Nothing to sort.\n");
continue;
} else if(str_quantity == 1){
printf("There is only one string in the box. Nothing to sort.\n");
continue;
}
sort_string(strbox, str_quantity);
printf("Sorting . . . Done!\n");
} else if(!strcmp(cmd, "status")){
(str_quantity == 0) ? printf("The String Box is empty.\n") :
(str_quantity == 1) ? printf("There is 1 string in the box.\n") :
printf("There are %d strings in the box.\n", str_quantity);
} else if(!strcmp(cmd, "help")){
help_prompt();
} else if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit")){
for(int i = 0; i < str_quantity; i++){
if(strbox[i] != NULL){
unreleased_count++;
free(strbox[i]);
strbox[i] = NULL;
}
}
free(strbox);
printf("String quantity: %d, Unreleased space quantity: %d\n", str_quantity, unreleased_count);
printf("The String Box is terminated. Bye!\n");
quit = true;
} else {
printf("Unknown command: [%s]\nEnter \"help\" for instructions.\n", cmd);
}
}
free(cmd);
return 0;
}
這是一個字串箱的 C 語言的主程式,能夠根據使用者輸入的指令新增字串到字串箱儲存、從字串箱中刪除字串、列出字串箱當前儲存的所有字串以及對所有字串進行 A-z 的排序。以下是同學需要實作的五個函式:
請同學們分別將上述 5 個函式在 StringBox.c 與 StringBox.h 分別完成函式的 實作(Implementation)與其 原型(Prototype)宣告。
本題的相關程式將使用以下的Makefile進行編譯:
all: Main.c StringBox.o gcc Main.c StringBox.o StringBox.o: StringBox.c StringBox.h gcc -c StringBox.c clean: rm -f *.o *.out *~
本題可參考以下的執行結果:
[3:23 user@ws hw] ./a.out↵
Welcome▴to▴the▴String▴Box!↵
You▴can▴use▴the▴following▴commands:↵
--------------------------------------------↵
[insert]▴or▴[add]▴-▴Insert▴a▴new▴string↵
[list]▴or▴[ls]▴▴▴▴-▴List▴all▴strings↵
[delete]▴or▴[rm]▴▴-▴Delete▴a▴string↵
[sort]▴▴▴▴▴▴▴▴▴▴▴▴-▴Sort▴the▴strings↵
[status]▴▴▴▴▴▴▴▴▴▴-▴Show▴the▴current▴number▴of▴strings↵
[help]▴▴▴▴▴▴▴▴▴▴▴▴-▴Show▴this▴help▴message↵
[quit]▴or▴[exit]▴▴-▴Exit▴the▴String▴Box↵
--------------------------------------------↵
>>▴add↵
Input▴a▴string:▴party.nptu.edu.tw↵
The▴string▴[party.nptu.edu.tw]▴has▴been▴stored.↵
--------------------------------------------↵
>>▴add↵
Input▴a▴string:▴ruby▴chan↵
The▴string▴[ruby▴chan]▴has▴been▴stored.↵
--------------------------------------------↵
>>▴add↵
Input▴a▴string:▴nanika▴suki↵
The▴string▴[nanika▴suki]▴has▴been▴stored.↵
--------------------------------------------↵
>>▴add↵
Input▴a▴string:▴python▴php▴js↵
The▴string▴[python▴php▴js]▴has▴been▴stored.↵
--------------------------------------------↵
>>▴add↵
Input▴a▴string:▴c▴c++▴java▴ts↵
The▴string▴[c▴c++▴java▴ts]▴has▴been▴stored.↵
--------------------------------------------↵
>>▴add↵
Input▴a▴string:▴windows▴11▴home↵
The▴string▴[windows▴11▴home]▴has▴been▴stored.↵
--------------------------------------------↵
>>▴ls▴-la↵
Unknown▴command:▴[ls▴-la]↵
Enter▴“help”▴for▴instructions.↵
--------------------------------------------↵
>>▴add↵
Input▴a▴string:▴macOS▴15▴sequoia↵
The▴string▴[macOS▴15▴sequoia]▴has▴been▴stored.↵
--------------------------------------------↵
>>▴ls↵
The▴strings▴in▴the▴box▴are▴listed▴as▴follows:↵
1.▴[party.nptu.edu.tw]↵
2.▴[ruby▴chan]↵
3.▴[nanika▴suki]↵
4.▴[python▴php▴js]↵
5.▴[c▴c++▴java▴ts]↵
6.▴[windows▴11▴home]↵
7.▴[macOS▴15▴sequoia]↵
--------------------------------------------↵
>>▴rm↵
The▴strings▴in▴the▴box▴are▴listed▴as▴follows:↵
1.▴[party.nptu.edu.tw]↵
2.▴[ruby▴chan]↵
3.▴[nanika▴suki]↵
4.▴[python▴php▴js]↵
5.▴[c▴c++▴java▴ts]↵
6.▴[windows▴11▴home]↵
7.▴[macOS▴15▴sequoia]↵
Please▴enter▴the▴index▴of▴the▴string▴to▴delete('0'▴for▴cancellation):▴4↵
The▴string▴at▴index▴4▴has▴been▴deleted.↵
--------------------------------------------↵
>>▴ls↵
The▴strings▴in▴the▴box▴are▴listed▴as▴follows:↵
1.▴[party.nptu.edu.tw]↵
2.▴[ruby▴chan]↵
3.▴[nanika▴suki]↵
4.▴[c▴c++▴java▴ts]↵
5.▴[windows▴11▴home]↵
6.▴[macOS▴15▴sequoia]↵
--------------------------------------------↵
>>▴add↵
Input▴a▴string:▴Tralalelo▴tralala↵
The▴string▴[Tralalelo▴tralala]▴has▴been▴stored.↵
--------------------------------------------↵
>>▴ls↵
The▴strings▴in▴the▴box▴are▴listed▴as▴follows:↵
1.▴[party.nptu.edu.tw]↵
2.▴[ruby▴chan]↵
3.▴[nanika▴suki]↵
4.▴[c▴c++▴java▴ts]↵
5.▴[windows▴11▴home]↵
6.▴[macOS▴15▴sequoia]↵
7.▴[Tralalelo▴tralala]↵
--------------------------------------------↵
>>▴sort↵
Sorting▴.▴.▴.▴Done!↵
--------------------------------------------↵
>>▴ls↵
The▴strings▴in▴the▴box▴are▴listed▴as▴follows:↵
1.▴[Tralalelo▴tralala]↵
2.▴[c▴c++▴java▴ts]↵
3.▴[macOS▴15▴sequoia]↵
4.▴[nanika▴suki]↵
5.▴[party.nptu.edu.tw]↵
6.▴[ruby▴chan]↵
7.▴[windows▴11▴home]↵
--------------------------------------------↵
>>▴rm↵
The▴strings▴in▴the▴box▴are▴listed▴as▴follows:↵
1.▴[Tralalelo▴tralala]↵
2.▴[c▴c++▴java▴ts]↵
3.▴[macOS▴15▴sequoia]↵
4.▴[nanika▴suki]↵
5.▴[party.nptu.edu.tw]↵
6.▴[ruby▴chan]↵
7.▴[windows▴11▴home]↵
Please▴enter▴the▴index▴of▴the▴string▴to▴delete('0'▴for▴cancellation):▴7↵
The▴string▴at▴index▴7▴has▴been▴deleted.↵
--------------------------------------------↵
>>▴exit↵
String▴quantity:▴6,▴Unreleased▴space▴quantity:▴6↵
The▴String▴Box▴is▴terminated.▴Bye!↵
[3:23 user@ws hw]
請參考課本程式演練21(12-29頁)的紀念品商店程式範例,將其原本僅處理不超過10筆商品數量的試用版,改為不限商品數量的正式版。現在請參考以下修改過後的Main.c主程式:
#include <stdio.h>
#include <stdlib.h>
#include "SouvenirShop.h"
void FreeShelf() {
if (shelf != NULL) {
free(shelf);
shelf = NULL;
}
}
void help() {
printf("Options:\n");
printf("[i] - Insert a souvenir\n");
printf("[r] - Remove a souvenir\n");
printf("[f] - Find a souvenir\n");
printf("[l] - List shelf\n");
printf("[h] - Help\n");
printf("[s] - Show shelf capacity & filled\n");
printf("[q] - Quit\n");
}
int main() {
SouvenirInit();
char opt = '\0';
help();
while (opt != 'q') {
printf("cmd > ");
scanf(" %c", &opt);
switch (opt) {
case 'i':
SouvenirInsert();
break;
case 'r':
SouvenirRemove();
break;
case 'l':
SouvenirList();
break;
case 'f':
SouvenirFind();
break;
case 'h':
help();
break;
case 's':
SouvenirShowCapacityNFilled();
break;
case 'q':
printf("Bye!\n");
break;
default:
printf("Invalid option\n");
}
}
FreeShelf();
return 0;
}
關於商品的結構體以及其它所需的全域變數與常數,已定義於以下的Required.h:
#define MIN_SOUVENIRS 2
typedef enum {
book = 'b',
keychain = 'k',
t_shirt = 't'
} Type;
typedef enum {
copper = 'c',
steel = 's',
woods = 'w',
plastic = 'p'
} KeychainMaterial;
typedef enum { XS, S, M, L, XL, XXL } TShirtSize;
typedef struct {
int id;
float price;
Type type;
union {
char author[21]; // For book
KeychainMaterial material; // For keychain
TShirtSize size; // For t-shirt
} attribute;
} Souvenir;
extern Souvenir *shelf;
extern int filled;
extern int capacity;
請接續完成兩個程式檔案SouvenirShop.c與SouvenirShop.h,以分別完成下列的6 個函式的實作(Implementation)與其原型(Prototype)宣告:
本題的相關程式將使用以下的Makefile進行編譯:
all: Main.c SouvenirShop.o gcc Main.c SouvenirShop.o SouvenirShop.o: SouvenirShop.c SouvenirShop.h Required.h gcc -c SouvenirShop.c clean: rm -rf *.*~ *~ *.o a.*
本題可參考以下的執行結果:
[3:23 user@ws hw] ./a.out↵
Options:↵
[i]▴-▴Insert▴a▴souvenir↵
[r]▴-▴Remove▴a▴souvenir↵
[f]▴-▴Find▴a▴souvenir↵
[l]▴-▴List▴shelf↵
[h]▴-▴Help↵
[s]▴-▴Show▴shelf▴capacity▴&▴filled↵
[q]▴-▴Quit↵
cmd▴>▴i↵
ID?▴1101↵
Price?▴34↵
Type▴[(b)ook,▴(k)eychain,▴(t)-shirt]?▴b↵
Author?▴Mcqueen▴kachow↵
Souvenir▴added↵
cmd▴>▴i↵
ID?▴1102↵
Price?▴45↵
Type▴[(b)ook,▴(k)eychain,▴(t)-shirt]?▴t↵
Size▴(XS,▴S,▴M,▴L,▴XL,▴XXL)?▴XS↵
Souvenir▴added↵
cmd▴>▴s↵
Shelf▴capacity:▴2↵
Souvenirs▴filled:▴2↵
cmd▴>▴i↵
Expanding▴for▴insufficient▴capacity!↵
ID?▴1103↵
Price?▴104↵
Type▴[(b)ook,▴(k)eychain,▴(t)-shirt]?▴k↵
Material▴[(c)opper,▴(s)teel,▴(w)oods,▴(p)lastic]?▴s↵
Souvenir▴added↵
cmd▴>▴s↵
Shelf▴capacity:▴4↵
Souvenirs▴filled:▴3↵
cmd▴>▴i↵
ID?▴1001↵
Price?▴92↵
Type▴[(b)ook,▴(k)eychain,▴(t)-shirt]?▴b↵
Author?▴Perry▴the▴Platypus↵
Souvenir▴added↵
cmd▴>▴s↵
Shelf▴capacity:▴4↵
Souvenirs▴filled:▴4↵
cmd▴>▴i↵
Expanding▴for▴insufficient▴capacity!↵
ID?▴37↵
Price?▴90↵
Type▴[(b)ook,▴(k)eychain,▴(t)-shirt]?▴f↵
Invalid▴type↵
cmd▴>▴i↵
ID?▴37↵
Price?▴90↵
Type▴[(b)ook,▴(k)eychain,▴(t)-shirt]?▴t↵
Size▴(XS,▴S,▴M,▴L,▴XL,▴XXL)?▴l↵
Invalid▴T-shirt▴size↵
cmd▴>▴l↵
[ID:▴1101][Price:▴\$34.00][Type:▴Book,▴Author:▴Mcqueen▴kachow]↵
[ID:▴1102][Price:▴\$45.00][Type:▴T-Shirt,▴Size:▴XS]↵
[ID:▴1103][Price:▴\$104.00][Type:▴Keychain,▴Material:▴Steel]↵
[ID:▴1001][Price:▴\$92.00][Type:▴Book,▴Author:▴Perry▴the▴Platypus]↵
cmd▴>▴f↵
ID?▴1002↵
ID▴1002▴not▴found↵
cmd▴>▴f↵
ID?▴1102↵
[ID:▴1102][Price:▴\$45.00][Type:▴T-Shirt,▴Size:▴XS]↵
cmd▴>▴r↵
ID?▴1234↵
ID▴1234▴not▴found↵
cmd▴>▴r↵
ID?▴1002↵
ID▴1002▴not▴found↵
cmd▴>▴r↵
ID?▴1102↵
Shrinking▴for▴excessive▴capacity!↵
Souvenir▴removed↵
cmd▴>▴l↵
[ID:▴1101][Price:▴\$34.00][Type:▴Book,▴Author:▴Mcqueen▴kachow]↵
[ID:▴1103][Price:▴\$104.00][Type:▴Keychain,▴Material:▴Steel]↵
[ID:▴1001][Price:▴\$92.00][Type:▴Book,▴Author:▴Perry▴the▴Platypus]↵
cmd▴>▴r↵
ID?▴1103↵
Souvenir▴removed↵
cmd▴>▴s↵
Shelf▴capacity:▴4↵
Souvenirs▴filled:▴2↵
cmd▴>▴r↵
ID?▴1101↵
Shrinking▴for▴excessive▴capacity!↵
Souvenir▴removed↵
cmd▴>▴l↵
[ID:▴1001][Price:▴\$92.00][Type:▴Book,▴Author:▴Perry▴the▴Platypus]↵
cmd▴>▴s↵
Shelf▴capacity:▴2↵
Souvenirs▴filled:▴1↵
cmd▴>▴q↵
Bye!↵
[3:23 user@ws hw]