當前位置:才華齋>計算機>C語言>

C語言scanf函式應用問題解答

C語言 閱讀(2.71W)

C語言的輸入是由系統提供的庫函式完成的。scanf函式是C語言中最常用且功能最強的輸入函式,但該函式如使用不慎,就會出現錯誤或得不到預想的結果。以下結果都是基於VC++6.0執行環境

C語言scanf函式應用問題解答

一、格式說明符和輸入項的三對應(型別、個數、順序)scanf函式格式中的格式說明(“%格式字元”)應與輸入項資料型別一致,個數相等、順序對應(除格式說明中出現“*”附加格式說明字元外)。示例一:inta,b;scanf("%d%d%d",&a,&b);printf("%d,%d",a,b);輸入“345”時,輸出“3,4”,沒有錯誤提示資訊,但是第三個數沒有接收的變數,也就沒有輸出。再如inta,b;scanf("%d",&a,&b);printf("%d,%d",a,b);輸入“34”時,輸出“3,-858993460”,a得到3,但b是一個隨機數,都是因為格式說明(“%格式字元”)與輸入項個數不一致造成的。再如structst{intnum;charname[10];intage;floatscore;}student;scanf("%d,%s,%d,%f",&student);輸入“10001,"zhang",23,68”,執行程式時,無出錯資訊,但student不能正確接收輸入資料。

應該寫成:scanf("%d,%s,%d,%f",&,,&,&e);保證格式說明與輸入項個數相等、一一對應,才能使student正確接收輸入資料。示例二:chara,b;scanf("%d%d",&a,&b);printf("%d,%d",a,b);輸入“34”時,輸出“3,4”,輸入整型資料,是字元型資料接收,但是結果正確,因為字元型資料在記憶體中的存放形式是整型資料。再如floata,b;scanf("%d%d",&a,&b);printf("%d,%d",a,b);輸入“34”時,輸出“0,918028288”,即a和b的結果都是隨機數,這就是輸入格式和接收的資料型別不一樣造成的。又如:inta,b;scanf("%f%f",&a,&b);printf("%d,%d",a,b);輸入“1.23.4”時,輸出“1067030938,1079613850”,即a和b的結果都是隨機數,這也是輸入格式和接收的資料型別不一樣造成的。

二、非格式說明符的輸入非格式說明符要求使用者原樣照寫輸入,既不能更改,又不能漏寫。示例一:inta,b;scanf("a=%d,b=%d",&a,&b);printf("%d,%d",a,b);輸入“12”(即1、2間用空格隔開),輸出“-858993460,-858993460”,無錯誤提示,但結果與輸入資料不一致,輸出a、b的值是隨機數。這就是因為scanf函式中設定的格式(“a=%d,b=%d”)(其中a=,b=均為普通字元)與輸入資料的格式(1、2間用空格間隔)不一致造成的,正確的輸入形式應為“a=1,b=2”(“,”也絕不能漏掉)。所以,為了保證正確輸入資料,輸入資料前首先看好程式中scanf函式設定的格式,再按照設定的格式正確輸入資料。示例二:scanf("%d,%d",&a,&b);輸入時應用以下形式:3,4↙注意3後面應是逗號,它與scanf函式中的“格式控制”中的逗號對應。如果輸入時不用逗號而用空格或其他字元是不對的。3□4↙(不對)3:4↙(不對)如果是scanf("%d□□%d",&a,&b);則輸入時兩個資料間應空兩個或更多個空格字元。如:3□□4↙或3□□□□4↙

三、附加格式說明符的說明示例一:inta,b;scanf("%2d%2d",&a,&b);printf("%d,%d",a,b);輸入“1234”,輸出“12,34”輸入“123”,輸出“12,3”輸入“123456”,輸出“12,34”因為格式中“d”格式字元表示輸入整型資料,“2”附加格式說明字元表示輸入資料所佔寬度為2,因此,無論使用者輸入什麼,系統都將自動擷取兩位賦給a,再擷取兩位賦給b。也就是說可以用附加格式說明符指定輸入資料所佔列數,系統將自動按它擷取所需資料。

再如scanf("%3c",&ch);如果從鍵盤上連續輸入3個字元abc,由於ch只能容納一個字元,系統就把第一個字元‘a’賦給ch。示例二:floata;scanf("%5.1f",&a);輸入“1234”,無錯誤提示,但a並不能接收輸入資料,輸出a的值為隨機數,再嘗試輸入別的資料,結果都為隨機數。使用者本意想用這樣的scanf格式輸入寬度為5位,小數部分為1位的小數,但得不到預想結果。因為,scanf函式中只有“域寬”(此處為5)附加格式說明字元(指定輸入資料所佔列數),而沒有在“小數位數”附加格式說明字元(只有printf函式有),應該去掉“.1”,即scanf("%5f",&a);或scanf("%f",&a);均可,此時輸入“123.4”即可接收。所以,應根據scanf函式中規定的格式字元及其附加格式說明字元使用,不能濫用,輸入資料時不能規定精度。示例三:doublex;scanf("%f",&x);輸入“123.4”,輸出x的`值為隨機數,沒有接收輸入的資料,再輸入別的資料,結果都為隨機數。這是因為使用者定義x為雙精度型資料,而用“%f”格式輸入資料時,不能接收,應該使用“%lf”或“%le”,即scanf("%lf",&x);此時輸入“123.4”即可接收。

因此長整型資料和雙精度型資料必須使用附加格式說明字元l,短整型資料必須使用附加格式說明字元h。示例四:inta,b;scanf("%2d,%*3d,%2d",&a,&b);輸入“12,345,67”,此時,12賦給a,67賦給b。注意:原則上“,%格式字元”應與“輸入項”(&a,&b)個數相等,一一對應,此處則出現了個數不等的情況(“%格式字元”項數為3,而輸入項數為2)。因為scanf函式中有附加格式說明字元“*”,加“*”項表示輸入的資料不賦給相應變數,因此輸入的“345”被跳過,接收下一個資料(“67”),致使“%格式字元”與“輸入項”個數可以不等的情況出現。在利用現成的一批資料時,有時不需要其中某些資料,可用此法跳過它們。例如scanf("%c%c",&a,&b);printf("%c%c",a,b);輸入A□B↙,輸出A□‘,A’給了字元變數a‘,□’作為合法字元給了字元變數b。這時我們改用scanf("%c%*c%c",&a,&b);輸入A□B↙,輸出AB,‘A’給了字元變數a‘,□’被%*c跳過‘,B’就給了字元變數b。可見,使用scanf函式時,要在scanf規定的格式字元及其附加格式說明字元下使用。既不能不用,又不能濫用。

四、注意輸入結束標誌①遇到空格,或者回車鍵,或者Tab鍵。如果相鄰兩個格式指示符之間,不指定資料分隔符(如逗號、冒號等),則相應的兩個輸入資料之間,至少用一個空格分開,或者用Tab鍵分開,或者輸入一個數據後,按回車,然後再輸入下一個資料。在用“%c”格式輸入字元時,空格字元和“轉義字元”都作為有效字元輸入。示例一:scanf("%d%d",&num1,&num2);假設給num1輸入12,給num2輸入36,則正確的輸入操作為:12□36↙或者:12↙36↙示例二:scanf("%c%c%c",&c1,&c2,&c3);如果從鍵盤輸入a□b□c↙則字元‘a’賦給c1,字元‘□’賦給c2,字元‘b’賦給c3。因為%c只要求讀入一個字元,後面不需要用空格作為兩個字元的間隔空格,因此空格作為下一個字元賦給c2。

故應該從鍵盤輸入abc↙②遇到輸入域寬度結束。例如“%3d”,只取3列。示例一:scanf("%3d",&num1);如果從鍵盤輸入12345↙,則num1的值為123。③遇到非法輸入。例如,在輸入數值資料時,遇到字母等非數值符號(數值符號僅由數字字元0-9、小數點和正負號構成)。示例一:scanf("%d%c%f",&a,&b,&c);若輸入1234a1230.26↙第一個資料對應%d格式在輸入1234之後遇到的字母a,因此認為1234之後已沒有數字了,第一個資料到此結束,把1234送給變數a。字元‘a’送給變數b,由於%c只要求輸入一個字元,因此輸入字元a後不需要加空格,後面的數值應送給變數c。如果由於疏忽把本來應為1230.26錯打成123o.26,由於123後面出現字母‘o’,就認為該數值資料到此結束,把123送給c。

五、注意輸入項scanf函式中的“格式控制”後應當是變數地址,而不是變數名。示例一:intx;scanf("%d",&x);該格式中x前必須加地址符&表示x所在的地址,即輸入資料所在的位置,如寫成intx;scanf("%d",x);則出現寫記憶體錯誤,無法執行應用程式。也有人常在陣列名前加地址符&。示例二:charc[10];scanf("%s",&c);這也是錯誤的。因為陣列名錶示陣列的起始地址,已經指出輸入資料的位置了,再使用地址符&即成為二級指標,意義截然不同,應改為charc[10];scanf("%s",c);因此,scanf函式中的“格式控制”後面只要寫成指標型(一級指標)資料指出輸入資料所在的位置即可,不能機械搬用,要明確實際含義。