if (!strcmp(instruction, "delete")) { state = N; printf("\n請輸入要刪除的帳號: "); scanf("%s", searchname); for (j = 0; j < SIZE; j++) { if (!strcmp(userID[j], searchname)) { state = Y; break; } } if (state == Y) { strcpy(userID[j], ""); strcpy(userCODE[j], ""); printf("\n%s 的帳號資料已刪除\n", searchname); } else if (state == N) { printf("\n%s 的帳號資料不存在,無法刪除\n", searchname); } continue; }
一開始跟搜尋是同樣的作法,要求管理員先輸入要刪除的帳號,然後做線性搜尋找到後用變數 j 記下該帳號的索引值,然後就把空字串拷貝進去,這樣一來,帳號就刪除了。
完整的範例程式碼及編譯執行,請繼續參考
可是這樣會有個問題,如果我們刪除某個前面、後面都有資料的帳號,我們去列印帳號名單會發生刪除帳號後面的資料不見的情況,雖然查詢還是找得到,問題是列印不出來。
為什麼會這樣子呢?想一想,其實發生的原因很簡單的,就是因為我們在列印功能裡添加了遇到空字串就結束列印的機制,所以遇到空字串就會列印不出來,要解決這個問題也很簡單,把 break 改成 continue 就行了,就會把 userID 中有內容的字串都印出來。
可是這樣刪除一個帳號,就平凡無故就佔去 userID 的一個空間, userID 的可用空間就變成 SIZE - 1 ,如果我們刪除了很多個使用者,會導致 userID 沒有空間繼續儲存新的帳號,因此程式執行會發生錯誤。
當然,加大 SIZE 會是一個解決方式,但這樣還是不太實際,所以我們提供另一個解決方法
if (!strcmp(instruction, "delete")) { state = N; printf("\n請輸入要刪除的帳號: "); scanf("%s", searchname); for (j = 0; j < SIZE; j++) { if (!strcmp(userID[j], searchname)) { state = Y; counter--; break; } } if (state == Y) { for (j; j < SIZE; j++) { strcpy(userID[j], userID[j + 1]); strcpy(userCODE[j], userCODE[j + 1]); } printf("\n%s 的帳號資料已刪除\n", searchname); } else if (state == N) { printf("\n%s 的帳號資料不存在,無法刪除\n", searchname); } continue; }
我們提供的解決方法在第 141 行到第 143 行
for (j; j < SIZE; j++) { strcpy(userID[j], userID[j + 1]); strcpy(userCODE[j], userCODE[j + 1]); }
也就是把 j + 1 拷貝給 j ,這樣索引 j 的陣列內容就會被 j + 1 的內容所取代,也就是說,我們依序把後面的元素向前移一個位置,因此完成刪除的工作。
另外要注意在第 134 行
counter--;
變數 counter 要做遞減,不然就沒有節省空間的效果了。
完整的範例程式碼及編譯執行,請繼續參考
問題與討論
- 第一個刪除帳號的方式有什麼優缺點?
- 把列印指令中的 break 改成 continue 有什麼優缺點?
- 想一想,還有其他刪除帳號資料的方法嗎?
沒有留言:
張貼留言