C語言scanf函數(shù)應(yīng)用問題

時(shí)間:2022-04-15 08:53:00

導(dǎo)語:C語言scanf函數(shù)應(yīng)用問題一文來源于網(wǎng)友上傳,不代表本站觀點(diǎn),若需要原創(chuàng)文章可咨詢客服老師,歡迎參考。

C語言scanf函數(shù)應(yīng)用問題

C語言的輸入是由系統(tǒng)提供的庫函數(shù)完成的。scanf函數(shù)是C語言中最常用且功能最強(qiáng)的輸入函數(shù),但該函數(shù)如使用不慎,就會(huì)出現(xiàn)錯(cuò)誤或得不到預(yù)想的結(jié)果。以下結(jié)果都是基于VC++6.0運(yùn)行環(huán)境。

一、格式說明符和輸入項(xiàng)的三對(duì)應(yīng)(類型、個(gè)數(shù)、順序)scanf函數(shù)格式中的格式說明(“%格式字符”)應(yīng)與輸入項(xiàng)數(shù)據(jù)類型一致,個(gè)數(shù)相等、順序?qū)?yīng)(除格式說明中出現(xiàn)“*”附加格式說明字符外)。示例一:inta,b;scanf("%d%d%d",&a,&b);printf("%d,%d",a,b);輸入“345”時(shí),輸出“3,4”,沒有錯(cuò)誤提示信息,但是第三個(gè)數(shù)沒有接收的變量,也就沒有輸出。再如inta,b;scanf("%d",&a,&b);printf("%d,%d",a,b);輸入“34”時(shí),輸出“3,-858993460”,a得到3,但b是一個(gè)隨機(jī)數(shù),都是因?yàn)楦袷秸f明(“%格式字符”)與輸入項(xiàng)個(gè)數(shù)不一致造成的。再如structst{intnum;charname[10];intage;floatscore;}student;scanf("%d,%s,%d,%f",&student);輸入“10001,"zhang",23,68”,運(yùn)行程序時(shí),無出錯(cuò)信息,但student不能正確接收輸入數(shù)據(jù)。

應(yīng)該寫成:scanf("%d,%s,%d,%f",&student.num,student.name,&student.age,&stu-dent.score);保證格式說明與輸入項(xiàng)個(gè)數(shù)相等、一一對(duì)應(yīng),才能使student正確接收輸入數(shù)據(jù)。示例二:chara,b;scanf("%d%d",&a,&b);printf("%d,%d",a,b);輸入“34”時(shí),輸出“3,4”,輸入整型數(shù)據(jù),是字符型數(shù)據(jù)接收,但是結(jié)果正確,因?yàn)樽址蛿?shù)據(jù)在內(nèi)存中的存放形式是整型數(shù)據(jù)。再如floata,b;scanf("%d%d",&a,&b);printf("%d,%d",a,b);輸入“34”時(shí),輸出“0,918028288”,即a和b的結(jié)果都是隨機(jī)數(shù),這就是輸入格式和接收的數(shù)據(jù)類型不一樣造成的。又如:inta,b;scanf("%f%f",&a,&b);printf("%d,%d",a,b);輸入“1.23.4”時(shí),輸出“1067030938,1079613850”,即a和b的結(jié)果都是隨機(jī)數(shù),這也是輸入格式和接收的數(shù)據(jù)類型不一樣造成的。

二、非格式說明符的輸入非格式說明符要求用戶原樣照寫輸入,既不能更改,又不能漏寫。示例一:inta,b;scanf("a=%d,b=%d",&a,&b);printf("%d,%d",a,b);輸入“12”(即1、2間用空格隔開),輸出“-858993460,-858993460”,無錯(cuò)誤提示,但結(jié)果與輸入數(shù)據(jù)不一致,輸出a、b的值是隨機(jī)數(shù)。這就是因?yàn)閟canf函數(shù)中設(shè)定的格式(“a=%d,b=%d”)(其中a=,b=均為普通字符)與輸入數(shù)據(jù)的格式(1、2間用空格間隔)不一致造成的,正確的輸入形式應(yīng)為“a=1,b=2”(“,”也絕不能漏掉)。所以,為了保證正確輸入數(shù)據(jù),輸入數(shù)據(jù)前首先看好程序中scanf函數(shù)設(shè)定的格式,再按照設(shè)定的格式正確輸入數(shù)據(jù)。示例二:scanf("%d,%d",&a,&b);輸入時(shí)應(yīng)用以下形式:3,4↙注意3后面應(yīng)是逗號(hào),它與scanf函數(shù)中的“格式控制”中的逗號(hào)對(duì)應(yīng)。如果輸入時(shí)不用逗號(hào)而用空格或其他字符是不對(duì)的。3□4↙(不對(duì))3:4↙(不對(duì))如果是scanf("%d□□%d",&a,&b);則輸入時(shí)兩個(gè)數(shù)據(jù)間應(yīng)空兩個(gè)或更多個(gè)空格字符。如: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”因?yàn)楦袷街小癲”格式字符表示輸入整型數(shù)據(jù),“2”附加格式說明字符表示輸入數(shù)據(jù)所占寬度為2,因此,無論用戶輸入什么,系統(tǒng)都將自動(dòng)截取兩位賦給a,再截取兩位賦給b。也就是說可以用附加格式說明符指定輸入數(shù)據(jù)所占列數(shù),系統(tǒng)將自動(dòng)按它截取所需數(shù)據(jù)。

再如scanf("%3c",&ch);如果從鍵盤上連續(xù)輸入3個(gè)字符abc,由于ch只能容納一個(gè)字符,系統(tǒng)就把第一個(gè)字符‘a(chǎn)’賦給ch。示例二:floata;scanf("%5.1f",&a);輸入“1234”,無錯(cuò)誤提示,但a并不能接收輸入數(shù)據(jù),輸出a的值為隨機(jī)數(shù),再嘗試輸入別的數(shù)據(jù),結(jié)果都為隨機(jī)數(shù)。用戶本意想用這樣的scanf格式輸入寬度為5位,小數(shù)部分為1位的小數(shù),但得不到預(yù)想結(jié)果。因?yàn)?,scanf函數(shù)中只有“域?qū)挕保ù颂帪?)附加格式說明字符(指定輸入數(shù)據(jù)所占列數(shù)),而沒有在“小數(shù)位數(shù)”附加格式說明字符(只有printf函數(shù)有),應(yīng)該去掉“.1”,即scanf("%5f",&a);或scanf("%f",&a);均可,此時(shí)輸入“123.4”即可接收。所以,應(yīng)根據(jù)scanf函數(shù)中規(guī)定的格式字符及其附加格式說明字符使用,不能濫用,輸入數(shù)據(jù)時(shí)不能規(guī)定精度。示例三:doublex;scanf("%f",&x);輸入“123.4”,輸出x的值為隨機(jī)數(shù),沒有接收輸入的數(shù)據(jù),再輸入別的數(shù)據(jù),結(jié)果都為隨機(jī)數(shù)。這是因?yàn)橛脩舳xx為雙精度型數(shù)據(jù),而用“%f”格式輸入數(shù)據(jù)時(shí),不能接收,應(yīng)該使用“%lf”或“%le”,即scanf("%lf",&x);此時(shí)輸入“123.4”即可接收。

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

四、注意輸入結(jié)束標(biāo)志①遇到空格,或者回車鍵,或者Tab鍵。如果相鄰兩個(gè)格式指示符之間,不指定數(shù)據(jù)分隔符(如逗號(hào)、冒號(hào)等),則相應(yīng)的兩個(gè)輸入數(shù)據(jù)之間,至少用一個(gè)空格分開,或者用Tab鍵分開,或者輸入一個(gè)數(shù)據(jù)后,按回車,然后再輸入下一個(gè)數(shù)據(jù)。在用“%c”格式輸入字符時(shí),空格字符和“轉(zhuǎn)義字符”都作為有效字符輸入。示例一:scanf("%d%d",&num1,&num2);假設(shè)給num1輸入12,給num2輸入36,則正確的輸入操作為:12□36↙或者:12↙36↙示例二:scanf("%c%c%c",&c1,&c2,&c3);如果從鍵盤輸入a□b□c↙則字符‘a(chǎn)’賦給c1,字符‘□’賦給c2,字符‘b’賦給c3。因?yàn)?c只要求讀入一個(gè)字符,后面不需要用空格作為兩個(gè)字符的間隔空格,因此空格作為下一個(gè)字符賦給c2。

故應(yīng)該從鍵盤輸入abc↙②遇到輸入域?qū)挾冉Y(jié)束。例如“%3d”,只取3列。示例一:scanf("%3d",&num1);如果從鍵盤輸入12345↙,則num1的值為123。③遇到非法輸入。例如,在輸入數(shù)值數(shù)據(jù)時(shí),遇到字母等非數(shù)值符號(hào)(數(shù)值符號(hào)僅由數(shù)字字符0-9、小數(shù)點(diǎn)和正負(fù)號(hào)構(gòu)成)。示例一:scanf("%d%c%f",&a,&b,&c);若輸入1234a1230.26↙第一個(gè)數(shù)據(jù)對(duì)應(yīng)%d格式在輸入1234之后遇到的字母a,因此認(rèn)為1234之后已沒有數(shù)字了,第一個(gè)數(shù)據(jù)到此結(jié)束,把1234送給變量a。字符‘a(chǎn)’送給變量b,由于%c只要求輸入一個(gè)字符,因此輸入字符a后不需要加空格,后面的數(shù)值應(yīng)送給變量c。如果由于疏忽把本來應(yīng)為1230.26錯(cuò)打成123o.26,由于123后面出現(xiàn)字母‘o’,就認(rèn)為該數(shù)值數(shù)據(jù)到此結(jié)束,把123送給c。

五、注意輸入項(xiàng)scanf函數(shù)中的“格式控制”后應(yīng)當(dāng)是變量地址,而不是變量名。示例一:intx;scanf("%d",&x);該格式中x前必須加地址符&表示x所在的地址,即輸入數(shù)據(jù)所在的位置,如寫成intx;scanf("%d",x);則出現(xiàn)寫內(nèi)存錯(cuò)誤,無法運(yùn)行.exe應(yīng)用程序。也有人常在數(shù)組名前加地址符&。示例二:charc[10];scanf("%s",&c);這也是錯(cuò)誤的。因?yàn)閿?shù)組名表示數(shù)組的起始地址,已經(jīng)指出輸入數(shù)據(jù)的位置了,再使用地址符&即成為二級(jí)指針,意義截然不同,應(yīng)改為charc[10];scanf("%s",c);因此,scanf函數(shù)中的“格式控制”后面只要寫成指針型(一級(jí)指針)數(shù)據(jù)指出輸入數(shù)據(jù)所在的位置即可,不能機(jī)械搬用,要明確實(shí)際含義。