糯米文學吧

位置:首頁 > 計算機 > C語言

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

C語言2.67W

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函數中的“格式控制”後面只要寫成指針型(一級指針)數據指出輸入數據所在的位置即可,不能機械搬用,要明確實際含義。