網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
scanf函數(shù)的原樣輸入的坑及解決
scanf函數(shù)是C語(yǔ)言里一個(gè)輸入函數(shù),但其有很多地方需要注意:
1、scanf函數(shù)格式控制后面輸入
的應(yīng)該是變量的地址而不是變量本身(即變量名)
例,輸入a,b 兩個(gè)整型變量的值的時(shí)候,很多初學(xué)者會(huì)寫成
scanf("%d %d",a,b)
這樣寫是錯(cuò)的,應(yīng)該寫成
scanf("%d %d",&a,&b)
2、scanf函數(shù)的輸入是有順序的
例如:
scanf(“%d %d”,&a,&b)
第一個(gè)%d是屬于a的,第二個(gè)%d是屬于b的
3、最重要的一點(diǎn)就是scanf切記要原樣輸入
即:
scanf(“a = %d,b = %d”,&a,&b);
輸入的是時(shí)候應(yīng)該寫成“a = 1,b = 2”,記住逗號(hào)都要原樣輸入。
若是這樣的話;
scanf(“a = %d b = %d”,&a,&b);
這樣的話就要寫成“a = 1 b =2”就連空格都要原樣輸入
總之一句話,除了占位符%d,%f,%lf等之類外的其他所有東西都要原樣輸入,包括空格,逗號(hào)
4、還有一個(gè)
如果scanf("%d %d %d",&a,&b,&c);,那么這時(shí)候可以在輸入界面輸入一個(gè)再按回車再輸入下一個(gè)這樣也是可以的,也可以按照這個(gè)格式在一行中進(jìn)行原樣輸入。
總之中間有空格的就用空格隔開(kāi),如果是逗號(hào)的就用逗號(hào)來(lái)隔開(kāi),如果什么都沒(méi),即連在一塊的話就按照輸入格式輸入即可。
scanf輸入多個(gè)數(shù)據(jù)出現(xiàn)的問(wèn)題
問(wèn)題引出
如果使用scanf函數(shù)一次輸入多個(gè)數(shù)據(jù),只能是整型和浮點(diǎn)型,如果有char字符型混合輸入,就會(huì)出現(xiàn)問(wèn)題:
圖中可以看到:num3的值并沒(méi)有打印出來(lái),出現(xiàn)這種情況的原因是什么呢???
執(zhí)行原理
讓我們先大概的過(guò)一下里面的執(zhí)行原理:
- 在執(zhí)行scanf函數(shù)的時(shí)候,會(huì)讓用戶輸入一個(gè)數(shù)據(jù),數(shù)據(jù)輸入完畢之后,并不是將這個(gè)數(shù)據(jù)直接賦值給變量,而是先將數(shù)據(jù)存儲(chǔ)在緩沖區(qū),輸入的任何數(shù)據(jù)都會(huì)存儲(chǔ)在緩沖區(qū)中
- 在執(zhí)行scanf函數(shù)的時(shí)候,會(huì)先檢查緩沖區(qū)中是否有數(shù)據(jù),如果緩沖區(qū)中沒(méi)有數(shù)據(jù),那么就會(huì)讓用戶從鍵盤輸入,如果緩沖區(qū)中有數(shù)據(jù),直接從緩沖區(qū)中將數(shù)據(jù)拿出來(lái),不會(huì)讓用戶輸入數(shù)據(jù)
- 當(dāng)從緩沖區(qū)中拿數(shù)據(jù)的時(shí)候,如果要拿的數(shù)據(jù)的類型是整型或者實(shí)型,如果拿到的數(shù)據(jù)的類型是空格、回車、Tab鍵,就會(huì)被自動(dòng)忽略,繼續(xù)往下拿;如果要拿的數(shù)據(jù)是字符型,不會(huì)忽略任何數(shù)據(jù)
程序分析
我們來(lái)分析下面的一段程序:程序中要求用戶輸入一個(gè)整型數(shù)據(jù)num1,但是這個(gè)時(shí)候我們偏偏輸入兩個(gè)整型數(shù)據(jù)10、20,這個(gè)時(shí)候緩沖區(qū)其實(shí)有四個(gè)數(shù)據(jù):10、空格、20、換行,執(zhí)行第一個(gè)printf后結(jié)果為10,這是我們事先預(yù)料好的;當(dāng)?shù)诙€(gè)scanf執(zhí)行的時(shí)候,程序根本就不會(huì)讓用戶輸入數(shù)據(jù),因?yàn)榫彌_區(qū)中已經(jīng)有整型數(shù)據(jù)20了【當(dāng)從緩沖區(qū)中拿數(shù)據(jù)的時(shí)候,如果要拿的數(shù)據(jù)的類型是整型或者實(shí)型,如果拿到的數(shù)據(jù)的類型是空格、回車、Tab鍵,就會(huì)被自動(dòng)忽略,繼續(xù)往下拿】,所以最終程序會(huì)直接打印出num2=20
讓我們?cè)倩仡^看第一個(gè)程序:為什么num3的值打印出來(lái)的結(jié)果為空???
執(zhí)行完第11行程序以后,緩沖區(qū)中的數(shù)據(jù)為10、空格、2.5、空格、a、換行;打印num1、num2的值的時(shí)候,因?yàn)槭钦突蛘吒↑c(diǎn)型,程序會(huì)自動(dòng)忽略空格和換行,所以輸出結(jié)果為num1=10,num2=2.500000;但是num3是一個(gè)字符型的數(shù)據(jù),程序并不會(huì)忽略任何的數(shù)據(jù),最后打印出來(lái)的結(jié)果為num3= ;【這里打印出來(lái)了一個(gè)空格,并不是空】
解決方案
那這個(gè)時(shí)候就有問(wèn)題了,如果scanf輸入多個(gè)數(shù)據(jù)中包含字符型數(shù)據(jù)時(shí),我就是想要輸出來(lái)字符型數(shù)據(jù),該怎么做呢???
解決方案:通過(guò)rewind(stdin);這行代碼把緩沖區(qū)中的數(shù)據(jù)全部清空,這個(gè)時(shí)候緩沖區(qū)中沒(méi)有任何數(shù)據(jù)了
寫C代碼時(shí),如果遇到整型、浮點(diǎn)型、字符型同時(shí)出現(xiàn)在scanf函數(shù)中的時(shí)候,要十分注意緩沖區(qū)中數(shù)據(jù)的情況??!
原文鏈接:https://blog.csdn.net/weixin_51976284/article/details/123489023
相關(guān)推薦
- 2022-12-14 WPF實(shí)現(xiàn)XAML轉(zhuǎn)圖片的示例詳解_C#教程
- 2022-10-19 python列表[list]和元組(tuple)詳情_(kāi)python
- 2022-07-15 SQL?Server中的排名函數(shù)與分析函數(shù)詳解_MsSql
- 2022-12-26 kubernetes數(shù)據(jù)持久化StorageClass動(dòng)態(tài)供給實(shí)現(xiàn)詳解_云和虛擬化
- 2022-06-25 Python中最強(qiáng)大的錯(cuò)誤重試庫(kù)(tenacity庫(kù))_python
- 2022-11-29 redis配置文件詳解
- 2022-10-12 Docker安裝RabbitMQ的超詳細(xì)步驟_docker
- 2022-10-12 Go?Excelize?API源碼解析GetSheetFormatPr使用示例_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支