從鍵盤讀入實數,鍵盤讀入實數

來源:互聯網
上載者:User

從鍵盤讀入實數,鍵盤讀入實數

編製一個從鍵盤讀入實數的函數readreal(double *rp)。函數將讀入的實數字元列換成實數後,利用指標參數rp,將實數存於指標所指向的變數*rp

解析:
函數在返回之前,將最後讀入的結束實數字元列的字元返還給系統,以便隨後讀字元時能再次讀入該字元。函數若能正常讀入實數,函數返回整數1,如果函數在讀入過程中,未遇到數字元之前,遇到不能構成數位情況,函數返回-1,表示為讀到實數。

在輸入實數時,在實數之前可以有一個數不定的空白類字元,組成實數的字元列有數的符號字元,實數的整數部分,小數點和實數的小數部分,其中,某些部分可以預設。設實數字元列有以下幾種可能形式:

數符 整數部分
數符 整數部分
數符 整數部分.小數部分
數符 .小數部分

其中數符或為空白,或為’+’,或為’-‘,分別代表不帶符號,帶正號,帶負號。整數部分和小數部分至少要有一個數字元組成。

上述實數形式說明,在實數轉換過程中,同一字元在不同情況下會有不同的意義。為標記當前實數轉換的不同情況,程式引入狀態變數,有狀態變數的不同值代表當前實數轉換過程中的不同情況。

共有以下多種不同的情況:正準備開始轉換,轉換了數的符號字元,正在轉換實數的整數部分,正在轉換實數的小數部分,發現輸入錯誤,轉換正常結束。設狀態變數為0表示正準備開始轉換,還未遇到任何與實數有關的字元;1表示已經遇到數的符號字元;2表示正在轉換實數的整數部分,3表示在未遇到數字字元之前先遇到小數點;4表示在轉換整數部分之後遇到小數點;5表示轉換髮現錯誤,6表示轉換正常結束。

讀函數另外有兩張表,一張是轉換函式表,一張是狀態表。函數反覆讀入字元,將字元分類,根據目前狀態和當前字元類調用對應轉換函式。

下面是程式的實現部分:

#include <stdio.h>#define ERR 5#define OK 6int status;double result,sig,scale;/* * 處理數的符號函數 */int sign(int c){    if(c = '-') /* 若為負號,取負 */        sig=-sig;}/** * @brief integer 轉換整數部分 * @param c 要被轉換的整數位 * @return 返回成功與否 */int integer(int c){    result = result * 10.0 + c - '0';}/** * @brief decimal 轉換小數部分 * @param c 要被轉換的小數位 * @return  返回成功與否 */int decimal(int c){    result += (c -'0') * scale;    scale /= 10;}/* 狀態表 *//* * 0 - 正準備開始轉換,還未遇到任何與實數有關的字元 * 1 - 已遇數的符號字元 * 2 - 正在轉換實數的整數部分 * 3 - 在未遇數字字元之前先遇到小數點 * 4 - 在轉換整數部分之後先遇到小數點 * 5 - 表示轉換髮現錯誤 * 6 - 轉換正常結束 */int statbl[][4]={    {1,2,3,ERR},    {ERR,2,3,ERR},    {OK,2,4,OK},    {ERR,4,ERR,ERR},    {OK,4,OK,OK}};/* 轉換函式表 */int (*funtbl[][4])() = {    {sign,integer,NULL,NULL},    {NULL,integer,NULL,NULL},    {NULL,integer,NULL,NULL},    {NULL,decimal,NULL,NULL},    {NULL,decimal,NULL,NULL}};/** * @brief readreal 用於對輸入的字串轉換成浮點數 * @param dp 轉換後的浮點數 * @return 返回是否轉換成功 */int readreal(double *dp){    int c,ckind;    sig = 1.0;    result = 0.0;    scale = 0.1;    while((c=getchar()) == ' ' || c == '\n' || c == '\t'); //跳過這些字元    status = 0; //重設初始狀態    for(;;){        /* 分類當前字元 */        if(c == '+' || c== '-') ckind = 0; /* 數的符號字元 */        else if(c >= '0' && c <= '9') ckind = 1; /* 數字元 */        else if(c == '.') ckind = 2; /* 小數點 */        else ckind = 3; /* 其他字元 */        if(funtbl[status][ckind]){            (*funtbl[status][ckind])(c); /* 執行相應的轉換函式 */        }        status = statbl[status][ckind]; /* 設定新的狀態 */        if(status == ERR || status == OK) break; /*結束,出錯或成功 */        c=getchar();    }    ungetc(c,stdin); /* 歸還數的結束符*/    if(status == OK){        *dp = result * sig;        return 1;    }    return -1;}int main(){    double x;    printf("Please input real numbers:\n");    while(readreal(&x) == 1)        printf("The real number is : %f\n",x);    return 0;}

下面是我的程式的運行結果:

這個程式剛開始的時候,我的思路是,從第1個元素開始遍曆,遍曆過程中,在遇到”.”之前,類似於上面integer()函數的實現方式,當遇到點之後,就類似於上面decimal()函數的實現方式,但是看了作者的源碼之後,發現需要學習一個做著的思路,思路敏捷,代碼整潔,需要好好學習。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.