C 語言初學教材 - 第三章 二維陣列

若是程式只能用預設的帳號密碼是不夠的,我們必須讓使用者自己建立專屬於自己的帳號密碼。



由於我們使用 exit 作為離開程式的指令,因此我們也可以用另一個英文單字來當作新建帳號密碼的指令, BBS 不就常用 new 當註冊的指令嗎?所以我們也用 new 囉!


因此在 while (1) 中要加入判斷使用者是否輸入 new 的 if 陳述,另外,還有一個問題,就是我們的程式應該允許多個使用者進行註冊新帳號密碼,這樣的話,我們豈不需要預先宣告多個儲存帳號密碼的字元陣列嗎?


解決這個問題的方是很簡單,就是一樣把字串(字元陣列)存入陣列之中,這樣一來就是陣列中儲存陣列,這稱之為二維陣列,需要兩個索引值,如
char userID[10][20];


上面宣告名為 userID 的二維字元陣列,這是說, userID 中可以儲存 10 個(第一個索引值)字元陣列,每個字元陣列可以儲存 20 個(第二個索引值)字元。


我們提供的版本如下
#include <stdio.h>
#include <string.h>

enum state {EXIT, RUN, WRONG_NAME, WRONG_CODE};

int main(void)
{
    // 宣告預設的帳號及密碼
    char userID[10][20];
    char userCODE[10][20];
    
    // 宣告暫存使用者輸入的帳號及密碼
    char inputName[20];
    char inputCode[20];
    
    // 宣告暫存新註冊的帳號及密碼
    char newName[20];
    char newCode[20];
    
    // 宣告暫存成功登入的帳號及密碼
    char whoName[20];
    char whoCode[20];
    
    // 宣告狀態變數、迴圈變數及陣列索引值變數
    int state, i;
    int counter;
    
    counter = 0;
    while (1) {
        state = WRONG_NAME;
        
        printf("login: ");
        scanf("%s", inputName);
        
        // "exit" 為內建指令,用來離開迴圈
        if (!strcmp(inputName, "exit")) {
            state = EXIT;
            printf("\n\n您將要離開本登入程式....\n\n");
            break;
        }
        
        // "new" 為內建指令,用來新建帳號密碼
        if (!strcmp(inputName, "new")) {
            state = RUN;
            
            printf("\n請輸入新的註冊帳號: ");
            scanf("%s", newName);
            printf("請輸入新的登入密碼: ");
            scanf("%s", newCode);
            
            strcpy(userID[counter], newName);
            strcpy(userCODE[counter], newCode);
            counter++;
            
            printf("\n新的帳號、密碼已建立,請重新登入....\n");
            continue;
        }
        
        // 從陣列中判斷是否有使用者輸入的帳號,若有才再繼續要求輸入密碼
        for (i = 0; i < 10; i++) {
            if (!strcmp(inputName, userID[i])) {
                printf("password: ");
                scanf("%s", inputCode);
            
                if (!strcmp(inputCode, userCODE[i])) {
                    strcpy(whoName, inputName);
                    strcpy(whoCode, inputCode);
                    
                    printf("\n\n哈囉, %s , 歡迎使用本登入程式...\n\n", whoName);
                    state = RUN;
                    break;
                }
                else {
                    state = WRONG_CODE;
                    break;
                }
            }
        }
        
        // 判斷目前狀態,顯示提示訊息
        if (state == RUN) {
            continue;
        }
        else if (state == WRONG_NAME) {
            printf("\n\n沒有這名使用者喔!請重新登入....\n\n");
            continue;
        }
        else if (state == WRONG_CODE) {
            printf("\n\n密碼錯誤,請重新登入....\n\n");
            continue;
        }
    }
    
    printf("\n\n程式即將關閉,所有建立的資料都會消失....\n");
    
    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:nc2.c
    功能:利用 while 迴圈設計的登入系統
    作者:張凱慶
    時間:西元2010年7月 */ 


程式的改變主要是多宣告了整數變數 i 及變數 counter ,變數 i 用作迴圈變數,變數 counter 則是用為記錄陣列的索引值。我們用陣列 userID 儲存使用者帳號,另外用陣列 userCODE 儲存陣列密碼,因此利用相同索引值就可以在兩個陣列中存取某個使用者的帳號、密碼。


所以進入迴圈前, counter 被設為 0 ,若有新增使用者,便會以 counter 作為陣列存取的索引,然後 counter 遞增 1 。


第 42 行到第 57 行,其為 new 指令的操作區域,注意,第 56 行用了 continue 陳述
continue;


這樣一來,建立帳號後便會回到迴圈開始的登入,接下來便是重新登入或用 exit 、 new 等指令。


來編譯執行看看吧!先輸入之前預設的使用者帳號



沒有這名使用者,因為現在都必須用 new 來新建帳號



依序輸入帳號名稱及密碼



最後離開程式



咦?為什麼程式結束後資料都會消失呢?


問題與討論
  1. 二維陣列還有哪些可資利用的地方?
  2. 設計一個程式,把九九法表存入二維陣列中。
  3. 設計一個指令,使之可以印出所以已註冊的使用者。
  4. 編譯後執行這個登入程式,新建一些帳號,然後離開,重新執行程式,看看原先建立的帳號還在不在?




沒有留言: