C 語言初學教材 - 第四章 刪除使用者帳號

如果要刪除使用者的帳號,有個簡單的想法就是拷貝空字串給要刪除的帳號位置,這樣一來,儲存該帳號的字元陣列就會變成空字串

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 要做遞減,不然就沒有節省空間的效果了。


完整的範例程式碼及編譯執行,請繼續參考


問題與討論
  1. 第一個刪除帳號的方式有什麼優缺點?
  2. 把列印指令中的 break 改成 continue 有什麼優缺點?
  3. 想一想,還有其他刪除帳號資料的方法嗎?




沒有留言: