日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言scanf函数奇遇记

發布時間:2024/7/19 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言scanf函数奇遇记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C語言scanf函數奇遇記

作者:ocean??? 撰寫日期:2011-11-20

博客鏈接:http://oceanspace.tk

?

? ? 看《The C Programming Language》中關于scanf函數部分時隨意敲了幾行代碼,本以為簡單的不得了,都有點“不屑于”敲,卻沒想到這一敲竟然敲出個不小的問題,涉及到好多東西啊,哈哈!下面把我這次的經歷和大家分享一下,希望也能對大家有所幫助。

一、代碼實例

我當時敲的代碼:

#include<stdio.h>

int main()

{

int a;

int b;

char mon[20];

int count;



count = scanf("%d,%s,%d", &a,mon,&b);

printf("%d,%s,%d\n",a,mon,b);

printf("%d\n",count);



return 0;

}

運行結果:

ocean@ocean-desktop:~/桌面$ ./re

12,fefe,45?? /*這是我的輸入*/

12,fefe,45,10359588

2

?????? 結果看起來挺像我們想要的結果的,只是最后多了個奇怪的數字;但仔細看下count的值我們就納悶了,怎么是2不是3呢?怎么scanf只讀了兩個值?到底怎么回事呢?先用gdb調試一下吧,看看a和mon里都是些什么。

二、GDB調試情況

(gdb) p a

$1 = 12

(gdb) p mon

$2 = "fe,45\000\377\277\245\324\025\000\060\340\021\000K\205\004\b"

?????? 明白了吧?原來fe,45作為一個整體被存到mon里了,b根本沒讀到值,顯示了個原內存里的亂七八糟的數值(不相信的話可以在程序開頭給b賦個值,最后結果肯定是輸出當初賦的值,因為根本沒有給b讀入新的值),scanf真的只讀了兩個值,所以count顯示2。那為什么會這樣呢?讓我們來看看scanf函數的相關信息吧。

三、scanf函數工作原理

?????? scanf()是從輸入流緩沖區中讀取值的,而并非從鍵盤(也就是終端)緩沖區讀取。往輸入流緩沖區送數據是遇到回車(\n)而結束的,這個\n會一起讀入輸入流緩沖區。scanf() 開始讀取輸入以后,會在遇到的第一個空白字符空格(blank)、制表符(tab)或者換行符(newline)處停止讀取。

?????? 格式控制字符串中有普通字符(非格式字符)時,這些字符作為輸入數據的分隔符,在scanf函數讀入數據時自動去掉。

?????? scanf()格式控制字符串中如果使用%s說明符,那么空白字符以外的所有字符都是可以接受的,所以scanf() 跳過空白字符直到遇到第一個非空白字符,然后保存再次遇到空白字符之前的所有非空白字符。這就意味著%s使scanf() 讀取一個單詞,也就是說,一個不包含空白字符的字符串。

?????? 好,讓我們分析下上述的結果是如何出現的吧。

四、原因分析

?????? 首先,scanf()跳過空白字符(這里沒有,因為第一個字符就是1)直到遇到一個非空白字符1,然后繼續讀2,讀到逗號這個非數字符號時scanf知道整數讀完了,將12賦給a,此時輸入流緩沖區中第一個開頭的字符是逗號;scanf繼續讀,讀到逗號與格式控制字符串的逗號匹配,pass;從f繼續讀,一直讀到下一個空白符——我們結束時敲的回車(scanf自動把這個回車符去掉了,沒有送到字符串里),字符串讀完了,此時輸入流緩沖區里第一個開頭的字符是我們敲的回車符;繼續讀,回車符與格式控制字符串里的逗號不批配,讀取失敗,不讀了。?? 綜上所述,scanf確實只讀了一個整數和一個字符串,返回值是2。

?????? 那有什么辦法實現用逗號作為間隔符的情況呢?下面提供兩種方法:

五、解決方法

1:

?????? scanf("%d,%[^,],%d", &a,mon,&b);

?????? printf("%d,%s,%d\n",a,mon,b);

?????? 相關知識:scanf中一種很少見但很有用的轉換字符:[...]和[ ^...]

?????? %[...]如果輸入的字符屬于方括號內字 符串中某個字符,那么就提取該字符;如果一經發現不屬于就結束提取。%[^...]如果一經發現輸入的字符屬于方括號內字符串中某個字符,那么就結束提取;如果不屬于就提取該字符。這兩種方法會自動加上一個字符串結束符到已經提取的字符后面。例如:

#include<stdio.h>

main()

{

char strings[100];

scanf("%[1234567890]",strings);

printf("%s",strings);

return 0;

}

運行,輸入:1234werew后,結果是:1234。

?????? 采用這種方法,讀完fefe后遇到逗號便結束字符串的讀取,繼續讀時輸入流緩沖區的逗號與格式控制字符串中逗號剛好匹配,成功!

2(不夠徹底):

scanf("%d,%s ,%d", &a,mon,&b);?? /*注意%s后面有個空格 */

printf("%d,%s,%d\n",a,mon,b);

并且在輸入時加個空格

12,fefe ,45?? /*fefe和逗號之間加個空白*/

?????? 相關知識:當scanf()格式控制字符串中出現空白時,表示取數時跳過任何空白。

scanf讀到fefe后的空格后結束字符串的讀取,此時輸入流緩沖區第一個字符為空格;繼續讀,由于格式控制字符串里有個空格,所以讀取時會跳過任何空白(不信可以在fefe后面多敲幾個空白試試,全都跳過,甚至連回車都跳過),讀到逗號匹配成功。

轉載于:https://www.cnblogs.com/happyblog/archive/2012/03/15/2398187.html

總結

以上是生活随笔為你收集整理的C语言scanf函数奇遇记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。