C 語言初學教材 - 第三章 使用者帳號的登入程式

BBS 、 E-mail 信箱、社群網站、論壇或是任何提供個人資料維護的網路服務,這些都需要一個使用者帳號的登入系統,使用者才可以登入使用專屬的服務。登入系統是種很常見的程式,我們利用 C 語言寫個簡化的雛型版本,說明 while 迴圈另一個常見的利用。



while (1) 迴圈是一個永真的迴圈,結束條件永遠為真時,也就是個無窮迴圈,所以我們必須提供一個離開迴圈的機制。以下為我們提供的例子
#include <stdio.h>
#include <string.h>

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

int main(void)
{
    // 宣告預設的帳號及密碼
    char userID[20] = "kaiching";
    char userCODE[20] = "12345678";
    
    // 宣告暫存使用者輸入的帳號及密碼
    char inputName[20];
    char inputCode[20];
    
    // 宣告暫存成功登入的帳號及密碼
    char whoName[20];
    char whoCode[20];
    
    // 宣告儲存目前狀態
    int state;
    
    state = RUN;
    while (1) {
        printf("login: ");
        scanf("%s", inputName);
        
        // "exit" 為內建指令,用來離開迴圈
        if (!strcmp(inputName, "exit")) {
            state = EXIT;
            printf("\n\n您將要離開本登入程式....\n\n");
            break;
        }
        
        // 判斷使用者輸入的帳號是否相同,若相同才再繼續要求輸入密碼
        if (!strcmp(inputName, userID)) {
            printf("password: ");
            scanf("%s", inputCode);
            
            if (!strcmp(inputCode, userCODE)) {
                strcpy(whoName, inputName);
                strcpy(whoCode, inputCode);
                
                printf("\n\n哈囉, %s , 歡迎使用本登入程式...\n\n", whoName);
                state = RUN;
            }
            else {
                state = WRONG_CODE;
            }
        }
        else {
            state = WRONG_NAME;
        }
        
        // 判斷目前狀態,顯示提示訊息
        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/
    檔名:nc1.c
    功能:利用 while 迴圈設計的登入系統
    作者:張凱慶
    時間:西元2010年7月 */


第 4 行,我們宣告列舉常數 state 記錄程式執行的狀態
enum state {EXIT, RUN, WRONG_NAME, WRONG_CODE};


EXIT 為程式離開 while (1) 迴圈,結束執行的狀態。 RUN 為 while (1) 迴圈持續執行的狀態。 WRONG_NAME 是使用者輸入錯誤帳號的狀態,而 WRONG_CODE 則是使用者輸入錯誤密碼的狀態。


第 9 行及第 10 行為宣告預設的帳號及密碼,預設的帳號設為 "kaiching" ,預設的密碼則是 "12345678" 。第 13 行及第 14 行則是宣告接受使用者輸入帳號、密碼的變數,第 17 行及第 18 行則是宣告另一組儲存使用者帳號、密碼的變數,這是當確認使用者登入成功後,才將帳號、密碼拷貝到這裡來。第 21 行則是宣告一個儲存目前狀態的變數 state 。


第 23 行,這是在進入 while (1) 迴圈之前,先將狀態設成 RUN
state = RUN;


第 24 行到第 67 行便是 while (1) 迴圈的範圍,這裡概略用空格分成四個部份。第一個部份是第 25 行及第 26 行,要求使用者輸入帳號。第二個部份是第 28 行到第 33 行,如果使用者輸入的是 exit ,其為我們保留特別的字串內容,作為離開 while (1) 迴圈之用,因此 exit 可以看成是這個登入程式的指令,作為離開程式之用。


第三個部份是第 35 行到第 53 行,這部份先判斷使用者輸入的帳號是否相同,如果相同才會繼續要求輸入密碼,結束這部份時會接著對於程式進行的狀態做設定。

第 36 行
if (!strcmp(inputName, userID)) {


我們在 if 後的小括弧呼叫標準函數庫 string.h 的函數 strcmp() ,這個含用來判斷兩個字串是否相同,相同就回傳 0 ,不相同會回傳非 0 的值,因此這裡需要加上邏輯運算子「非」 ! ,才能在個字串時執行底下要求繼續輸入密碼的部份。


同樣的,第 40 行是檢查密碼是否相符
if (!strcmp(inputCode, userCODE)) {


密碼相符的話,就是說使用者輸入了預設的帳號及密碼,然後程式先進行帳號密碼的備份工作,這裡利用了 string.h 的函數 strcpy() ,這個函數能夠把第二個參數的字串拷貝給第一個參數的字元陣列。接著向使用者印出歡迎訊息。後面第 45 行到第 53 行都是對狀態進行設定。


第四個部份,也就是從第 56 行到第 66 行則是依據狀態列印出程式的提示訊息。第 57 行、第 61 行及第 65 行都使用了
continue;


continue 為關鍵字之一,跟 break 是相對的使用。 break 陳述用來跳出迴圈,若是迴圈執行時遇到 continue 陳述,程式會直接略過 continue 底下的程事碼,直接進行下一輪。這裡已經是迴圈的最後,用 continue 只是讓程式在條件符合時,進行相關工作後直接進入迴圈的下一輪,而不必繼續執行底下的條件檢查,因此是給程式執行圖個方便而已,這裡用不用 continue 可以自行選擇。


明白這個 while (1) 是怎麼運作的嗎?來編譯玩看看吧!首先是登入畫面



輸入錯誤的使用者帳號



輸入正確的使用者帳號,但是輸入錯誤的密碼



輸入正確的使用者帳號及密碼



離開程式



問題與討論
  1. 除了 while (1) 之外,還有什麼方式可以設計永真的迴圈呢?
  2. 這個登入程式是怎麼結束 while (1) 迴圈的?
  3. 如果使用者輸入完帳號後,程式直接要求輸入密碼,然後才檢查是否有這名使用者,這樣的設計方式好不好?
  4. 想一想,除了網路服務外,有哪些地方也有用到使用者帳號的管理程式?




沒有留言: