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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

%d 跟%i 的区别以及scanf和sscanf的用法

發(fā)布時(shí)間:2025/3/12 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 %d 跟%i 的区别以及scanf和sscanf的用法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

scanf 用%i能夠獲得8/16進(jìn)制的值,
比如0011就是9,0x11就是17,當(dāng)然如果讀取到08或者09就會(huì)出錯(cuò)了。

scanf簡介

scanf函數(shù),與printf函數(shù)一樣,都被定義在stdio.h里,因此在使用scanf函數(shù)時(shí)要加上#include<stdio.h>。它是格式輸入函數(shù),即按用戶指定的格式從鍵盤上把數(shù)據(jù)輸入到指定的變量之中,其關(guān)鍵字最末一個(gè)字母f即為“格式”(format)之意

scanf函數(shù)的一般形式scanf(格式控制,地址表列)  int scanf(char *format[,argument,...]);  “格式控制”的含義同printf函數(shù);“地址表列”是由若干個(gè)地址組成的表列,可以是變量的地址,或字符串的首地址。  scanf()函數(shù)返回成功賦值的數(shù)據(jù)項(xiàng)數(shù),讀到文件末尾出錯(cuò)時(shí)則返回EOF。  例:使用scanf函數(shù)輸入數(shù)據(jù)。  在visual c++ 6.0上的編寫方式。

[cpp] view plain copy print?
  • #include<stdio.h>??
  • void?main()??
  • {??
  • ????int?a,b,c;??
  • ????printf("please?input?a,b,c");??
  • ????scanf("%d,%d,%d",&a,&b,&c);??
  • ????printf("a=%d,b=%d,c=%d",a,b,c);??
  • }??
  • #include<stdio.h> void main() {int a,b,c;printf("please input a,b,c");scanf("%d,%d,%d",&a,&b,&c);printf("a=%d,b=%d,c=%d",a,b,c); }


    在Dev-C++上運(yùn)行程序?yàn)?#xff1a;

    [cpp] view plain copy print?
  • #include<stdio.h>??
  • int?main()??
  • {??
  • ????int?a,b,c;??
  • ????printf("please?input?a,b,c");??
  • ????scanf("%d,%d,%d",&a,&b,&c);??
  • ????printf("a=%d,b=%d,c=%d",a,b,c);??
  • ????fflush(stdin);??
  • ????getchar();??
  • }??
  • #include<stdio.h> int main() {int a,b,c;printf("please input a,b,c");scanf("%d,%d,%d",&a,&b,&c);printf("a=%d,b=%d,c=%d",a,b,c);fflush(stdin);getchar(); }


    注意上面的scanf("%d,%d,%d",&a,&b,&c);中%d,%d,%d之間有逗號,在輸入數(shù)據(jù)時(shí)也要加逗號,如果去掉逗號,輸入時(shí)就不用逗號,而用空格,tab鍵或回車鍵將各個(gè)數(shù)據(jù)隔開

    格式字符說明%a,%A 讀入一個(gè)浮點(diǎn)值(僅C99有效)  %c 讀入一個(gè)字符  %d 讀入十進(jìn)制整數(shù)  %i 讀入十進(jìn)制,八進(jìn)制,十六進(jìn)制整數(shù)  %o 讀入八進(jìn)制整數(shù)  %x,%X 讀入十六進(jìn)制整數(shù)  %s 讀入一個(gè)字符串,遇空格、制表符或換行符結(jié)束。  %f,%F,%e,%E,%g,%G 用來輸入實(shí)數(shù),可以用小數(shù)形式或指數(shù)形式輸入。  %p 讀入一個(gè)指針  %u 讀入一個(gè)無符號十進(jìn)制整數(shù)  %n 至此已讀入值的等價(jià)字符數(shù)  %[] 掃描字符集合  %% 讀%符號  附加格式說明字符表修飾符說明   L/l 長度修飾符 輸入"長"數(shù)據(jù)  h 長度修飾符 輸入"短"數(shù)據(jù)  W 整型常數(shù) 指定輸入數(shù)據(jù)所占寬度  * 表示本輸入項(xiàng)在讀入后不賦值給相應(yīng)的變量

    scanf的返回值scanf的返回值有后面的參數(shù)決定  scanf("%d%d", &a, &b);  如果a和b都被成功讀入,那么scanf的返回值就是2  如果只有a被成功讀入,返回值為1  如果a和b都未被成功讀入,返回值為0  如果遇到錯(cuò)誤或遇到end of file,返回值為EOF。  且返回值為int型.

    使用scanf函數(shù)時(shí)應(yīng)該注意的問題

    1、scanf()中的變量必須使用地址。   

    2、scanf()的格式控制串可以使用其它非空白字符,但在輸入時(shí)必須輸入這些字符。  

    3、在用"%c"輸入時(shí),空格和“轉(zhuǎn)義字符”均作為有效字符。

    問題一

    ?scanf()函數(shù)不能正確接受有空格的字符串?如: I love you!  

    [cpp] view plain copy print?
  • #include?<stdio.h>  ??
  • int?main()??
  • {??
  • ????char?str[80];??
  • ????scanf("%s",str);??
  • ????printf("%s",str);??
  • ????return?0;??
  • }??
  • #include <stdio.h>   int main() {char str[80];scanf("%s",str);printf("%s",str);return 0; }


    輸入:I love you!  輸出:scanf()函數(shù)接收輸入數(shù)據(jù)時(shí),遇以下情況結(jié)束一個(gè)數(shù)據(jù)的輸入:(不是結(jié)束該scanf函數(shù),scanf函數(shù)僅在每一個(gè)數(shù)據(jù)域均有數(shù)據(jù),并按回車后結(jié)束)。  ① 遇空格、“回車”、“跳格”鍵。  ② 遇寬度結(jié)束。  ③ 遇非法輸入。  所以,上述程序并不能達(dá)到預(yù)期目的,scanf()掃描到"I"后面的空格就認(rèn)為對str的賦值結(jié)束,并忽略后面的"love you!".這里要注意是"love you!"還在鍵盤緩沖區(qū)(關(guān)于這個(gè)問題,網(wǎng)上我所見的說法都是如此,但是,我經(jīng)過調(diào)試發(fā)現(xiàn),其實(shí)這時(shí)緩沖區(qū)字符串首尾指針已經(jīng)相等了,也就是說緩沖區(qū)清空了,scanf()函數(shù)應(yīng)該只是掃描stdin流,這個(gè)殘存信息是在stdin中)。我們改動(dòng)一下上面的程序來驗(yàn)證一下:

    [cpp] view plain copy print?
  • #include?<stdio.h>??
  • #include<windows.h>??
  • int?main()??
  • {??
  • ????char?str[80];??
  • ????char?str1[80];??
  • ????char?str2[80];??
  • ????scanf("%s",str);/*此處輸入:I?love?you!?*/??
  • ????printf("%s",str);??
  • ????Sleep(5000);/*這里等待5秒,告訴你程序運(yùn)行到什么地方*/?/*不是sleep(5)?1,函數(shù)名是Sleep不是sleep。?
  • ????????????????????????????????????????2,C/C++中,unsigned?Sleep(unsigned)應(yīng)該是毫秒ms.?
  • ????????????????????????????????????????scanf("%s",str1);/*這兩句無需你再輸入,是對鍵盤盤緩沖區(qū)再掃描?*/??
  • ????scanf("%s",str2);/*這兩句無需你再輸入,是對鍵盤盤緩沖區(qū)再掃描?*/??
  • ????printf("/n%s",str1);??
  • ????printf("/n%s",str2);??
  • ????return?0;  ??
  • }??
  • #include <stdio.h> #include<windows.h> int main() {char str[80];char str1[80];char str2[80];scanf("%s",str);/*此處輸入:I love you! */printf("%s",str);Sleep(5000);/*這里等待5秒,告訴你程序運(yùn)行到什么地方*/ /*不是sleep(5) 1,函數(shù)名是Sleep不是sleep。2,C/C++中,unsigned Sleep(unsigned)應(yīng)該是毫秒ms.scanf("%s",str1);/*這兩句無需你再輸入,是對鍵盤盤緩沖區(qū)再掃描 */scanf("%s",str2);/*這兩句無需你再輸入,是對鍵盤盤緩沖區(qū)再掃描 */printf("/n%s",str1);printf("/n%s",str2);return 0;   }


    輸入:I love you!  輸出:  I  love  you!  好了,原因知道了,那么scanf()函數(shù)能不能完成這個(gè)任務(wù)?回答是:能!別忘了scanf()函數(shù)還有一個(gè) %[] 格式控制符(如果對%[]不了解的請查看本文的上篇),請看下面的程序: 

    [cpp] view plain copy print?
  • #include?"stdio.h"??
  • int?main()??
  • {??
  • ????char?string[50];/*scanf("%s",string);不能接收空格符*/??
  • ????scanf("%[^/n]",string);??
  • ????printf("%s/n",string);??
  • ????return?0;??
  • }??
  • #include "stdio.h" int main() {char string[50];/*scanf("%s",string);不能接收空格符*/scanf("%[^/n]",string);printf("%s/n",string);return 0; }


    ?

    問題二

    ?鍵盤緩沖區(qū)殘余信息問題

    [cpp] view plain copy print?
  • #include?<stdio.h>  ??
  • int?main()??
  • {??
  • ????int?a;??
  • ????char?c;???
  • ????do{??
  • ????????scanf("%d",&a);??
  • ????????scanf("%c",&c);??
  • ????????printf("a=%d?c=%c/n",a,c);/*printf("c=%d/n",c);*/??
  • ????}while(c!='N');??
  • }??
  • #include <stdio.h>   int main() {int a;char c; do{scanf("%d",&a);scanf("%c",&c);printf("a=%d c=%c/n",a,c);/*printf("c=%d/n",c);*/}while(c!='N'); }


    scanf("%c",&c);這句不能正常接收字符,什么原因呢?我們用printf("c=%d/n",c);將C用int表示出來,啟用printf("c=%d/n",c);這一句,看看scanf()函數(shù)賦給C到底是什么,結(jié)果是c=10 ,ASCII值為10是什么?換行即/n.對了,我們每擊打一下"Enter"鍵,向鍵盤緩沖區(qū)發(fā)去一個(gè)“回車”(/r),一個(gè)“換行"(/n),在這里/r被scanf()函數(shù)處理掉了(姑且這么認(rèn)為吧^_^),而/n被scanf()函數(shù)“錯(cuò)誤”地賦給了c.解決辦法:可以在兩個(gè)scanf()函數(shù)之后加個(gè)fflush(stdin);,還有加getch()?, getchar()也可以,但是要視具體scanf()語句加那個(gè),這里就不分析了,讀者自己去摸索吧。但是加fflush(stdin);不管什么情況都可行。  (  函數(shù)名: fflush  功 能: 清除一個(gè)流  用 法: int fflush(FILE *stream);  )

    [cpp] view plain copy print?
  • #include?<stdio.h>  ??
  • int?main()??
  • {??
  • ????int?a;??
  • ????char?c;???
  • ????do{??
  • ????????scanf("%d",&a);??
  • ????????fflush(stdin);??
  • ????????scanf("%c",&c);??
  • ????????fflush(stdin);??
  • ????????printf("a=%d?c=%c/n",a,c);???
  • ????}while(c!='N');??
  • }??
  • #include <stdio.h>   int main() {int a;char c; do{scanf("%d",&a);fflush(stdin);scanf("%c",&c);fflush(stdin);printf("a=%d c=%c/n",a,c); }while(c!='N'); }


    這里再給一個(gè)用“空格符”來處理緩沖區(qū)殘余信息的示例:運(yùn)行出錯(cuò)的程序:  

    [cpp] view plain copy print?
  • #include?<stdio.h>??
  • int?main()??
  • {??
  • ????int?i;??
  • ????char?j;??
  • ????for(i?=?0;i?<?10;i++)??
  • ????{??
  • ????????scanf("%c",&j);/*這里%前沒有空格*/??
  • ????}??
  • }??
  • #include <stdio.h> int main() {int i;char j;for(i = 0;i < 10;i++){scanf("%c",&j);/*這里%前沒有空格*/} }


    使用了空格控制符后: 

    [cpp] view plain copy print?
  • #include?<stdio.h>??
  • int?main()??
  • {??
  • ????int?i;??
  • ????char?j;??
  • ????for(i?=?0;i?<?10;i++)??
  • ????{??
  • ????????scanf("?%c",&j);/*注意這里%前有個(gè)空格*/??
  • ????}??
  • }??
  • #include <stdio.h> int main() {int i;char j;for(i = 0;i < 10;i++){scanf(" %c",&j);/*注意這里%前有個(gè)空格*/} }


    可以運(yùn)行看看兩個(gè)程序有什么不同。

    問題三

    ?如何處理scanf()函數(shù)誤輸入造成程序死鎖或出錯(cuò)?

    [cpp] view plain copy print?
  • #include?<stdio.h>  ??
  • int?main()??
  • {??
  • ????int?a,b,c;?/*計(jì)算a+b*/??
  • ????scanf("%d,%d",&a,&b);??
  • ????c=a+b;??
  • ????printf("%d+%d=%d",a,b,c);??
  • }??
  • #include <stdio.h>   int main() {int a,b,c; /*計(jì)算a+b*/scanf("%d,%d",&a,&b);c=a+b;printf("%d+%d=%d",a,b,c); }


    如上程序,如果正確輸入a,b的值,那么沒什么問題,但是,你不能保證使用者每一次都能正確輸入,一旦輸入了錯(cuò)誤的類型,你的程序不是死鎖,就是得到一個(gè)錯(cuò)誤的結(jié)果,呵呵,這可能所有人都遇到過的問題吧?解決方法:scanf()函數(shù)執(zhí)行成功時(shí)的返回值是成功讀取的變量數(shù),也就是說,你這個(gè)scanf()函數(shù)有幾個(gè)變量,如果scanf()函數(shù)全部正常讀取,它就返回幾。但這里還要注意另一個(gè)問題,如果輸入了非法數(shù)據(jù),鍵盤緩沖區(qū)就可能還個(gè)有殘余信息問題。正確的例程:  

    [cpp] view plain copy print?
  • #include?<stdio.h>??
  • int?main()??
  • {??
  • ????int?a,b,c;?/*計(jì)算a+b*/??
  • ????while(scanf("%d,%d",&a,&b)!=2)??
  • ????????fflush(stdin);??
  • ????c=a+b;??
  • ????printf("%d+%d=%d",a,b,c);??
  • }??
  • #include <stdio.h> int main() {int a,b,c; /*計(jì)算a+b*/while(scanf("%d,%d",&a,&b)!=2)fflush(stdin);c=a+b;printf("%d+%d=%d",a,b,c); }


    ?

    補(bǔ)充

    ?fflush(stdin)這個(gè)方法在GCC下不可用。(在VC6.0下可以)  以下是 C99 對 fflush 函數(shù)的定義:  int fflush(FILE *stream);  如果stream指向輸出流或者更新流(update stream),并且這個(gè)更新流  最近執(zhí)行的操作不是輸入,那么fflush函數(shù)將把任何未被寫入的數(shù)據(jù)寫入stream  指向的文件(如標(biāo)準(zhǔn)輸出文件stdout)。否則,fflush函數(shù)的行為是不確定的。  fflush(NULL)清空所有輸出流和上面提到的更新流。如果發(fā)生寫錯(cuò)誤,fflush  函數(shù)會(huì)給那些流打上錯(cuò)誤標(biāo)記,并且返回EOF,否則返回0。  由此可知,如果 stream 指向輸入流(如 stdin),那么 fflush 函數(shù)的行為是不確定的。故而使用  fflush(stdin) 是不正確的,至少是移植性不好的。  可采用如下方法:  /* 此函數(shù)可以和scanf函數(shù)一起使用,但使用%c輸入時(shí)要注意,即此函數(shù)只能用于緩沖區(qū)非空的情況 */ 

    void flush()

    {  

    ??? char c;  

    ??? while ((c=getchar()) != '/n'&&c!=EOF) ; 

    } 

    [cpp] view plain copy print?
  • #include?<stdio.h>??
  • int?main()??
  • {??
  • ????int?a,b,c;?/*計(jì)算a+b*/??
  • ????while(scanf("%d,%d",&a,&b)!=2)???
  • ????????flush();??
  • ????c=a+b;??
  • ????printf("%d+%d=%d",a,b,c);??
  • }??
  • #include <stdio.h> int main() {int a,b,c; /*計(jì)算a+b*/while(scanf("%d,%d",&a,&b)!=2) flush();c=a+b;printf("%d+%d=%d",a,b,c); }


    ?sscanf介紹

    sscanf() - 從一個(gè)字符串中讀進(jìn)與指定格式相符的數(shù)據(jù). 函數(shù)原型: int sscanf( const char *, const char *, ...); int sscanf(const char *buffer,const char *format,[argument ]...); buffer 存儲的數(shù)據(jù) format 格式控制字符串 argument 選擇性設(shè)定字符串 sscanf會(huì)從buffer里讀進(jìn)數(shù)據(jù),依照argument的設(shè)定將數(shù)據(jù)寫回。 說明: sscanf與scanf類似,都是用于輸入的,只是后者以鍵盤(stdin)為輸入源,前者以固定字符串為輸入源。 第一個(gè)參數(shù)可以是一個(gè)或多個(gè) {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符號} 注: 1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星號 (*) 表示跳過此數(shù)據(jù)不讀入. (也就是不把此數(shù)據(jù)讀入?yún)?shù)中) 2、{a|b|c}表示a,b,c中選一,[d],表示可以有d也可以沒有d。 3、width表示讀取寬度。 4、{h | l | I64 | L}:參數(shù)的size,通常h表示單字節(jié)size,I表示2字節(jié) size,L表示4字節(jié)size(double例外),l64表示8字節(jié)size。 5、type :這就很多了,就是%s,%d之類。 6、特別的:%*[width] [{h | l | I64 | L}]type 表示滿足該條件的被過濾掉,不會(huì)向目標(biāo)參數(shù)中寫入值 失敗返回0 ,否則返回格式化的參數(shù)個(gè)數(shù) 支持集合操作 %[a-z] 表示匹配a到z中任意字符,貪婪性(盡可能多的匹配) %[aB'] 匹配a、B、'中一員,貪婪性 %[^a] 匹配非a的任意字符,并且停止讀入,貪婪性 例子 1. 常見用法。 char buf[512] ; sscanf("123456 ", "%s", buf);//此處buf是數(shù)組名,它的意思是將123456以%s的形式存入buf中! printf("%s\n", buf); 結(jié)果為:123456 2. 取指定長度的字符串。如在下例中,取最大長度為4字節(jié)的字符串。 sscanf("123456 ", "%4s", buf); printf("%s\n", buf); 結(jié)果為:1234 3. 取到指定字符為止的字符串。如在下例中,取遇到空格為止字符串。 sscanf("123456 abcdedf", "%[^ ]", buf); printf("%s\n", buf); 結(jié)果為:123456 4. 取僅包含指定字符集的字符串。如在下例中,取僅包含1到9和小寫字母的字符串。 sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf); printf("%s\n", buf); 結(jié)果為:123456abcdedf 當(dāng)輸入: sscanf("123456abcdedfBCDEF","%[1-9A-Z]",buf); printf("%s\n",buf); 結(jié)果為:123456 5. 取到指定字符集為止的字符串。如在下例中,取遇到大寫字母為止的字符串。 sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf); printf("%s\n", buf); 結(jié)果為:123456abcdedf 6、給定一個(gè)字符串iios/12DDWDFF@122,獲取 / 和 @ 之間的字符串,先將 "iios/"過濾掉,再將非'@'的一串內(nèi)容送到buf中 sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf); printf("%s\n", buf); 結(jié)果為:12DDWDFF 7、給定一個(gè)字符串"hello, world",僅保留world。(注意:","之后有一空格,%s遇空格停止,加*則是忽略第一個(gè)讀到的字符串) sscanf("hello, world", "%*s%s", buf); printf("%s\n", buf); 結(jié)果為:world %*s表示第一個(gè)匹配到的%s被過濾掉,即hello被過濾了 如果沒有空格則結(jié)果為NULL。 sscanf的功能很類似于正則表達(dá)式, 但卻沒有正則表達(dá)式強(qiáng)大,所以如果對于比較復(fù)雜的字符串處理,建議使用正則表達(dá)式. //------------------------------------------------------- 用它來分隔類似這樣的字符串2006:03:18: int a, b, c; /*sscanf("2006:03:18", "%d:%d:%d", a, b, c); */ /*錯(cuò)誤方法, 要在變量a,b,c前加上取地址符, modified by huanmie_09*/ sscanf("2006:03:18", "%d:%d:%d", &a, &b, &c); 以及2006:03:18 - 2006:04:18: char sztime1[16] = "", sztime2[16] = ""; sscanf("2006:03:18 - 2006:04:18", "%s - %s", sztime1, sztime2); 但是后來,我需要處理2006:03:18-2006:04:18 僅僅是取消了‘-’兩邊的空格,卻打破了%s對字符串的界定。 我需要重新設(shè)計(jì)一個(gè)函數(shù)來處理這樣的情況?這并不復(fù)雜,但是,為了使所有的代碼都有統(tǒng)一的風(fēng)格,我需要改動(dòng)很多地方,把已有的sscanf替換成我自己的分割函數(shù)。我以為我肯定需要這樣做,并伴隨著對sscanf的強(qiáng)烈不滿而入睡;一覺醒來,發(fā)現(xiàn)其實(shí)不必。 format-type中有%[]這樣的type field。如果讀取的字符串,不是以空格來分隔的話,就可以使用%[]。 %[]類似于一個(gè)正則表達(dá)式。[a-z]表示讀取a-z的所有字符,[^a-z]表示讀取除a-z以外的所有字符。 所以那個(gè)問題也就迎刃而解了: sscanf("2006:03:18 - 2006:04:18", "%[0-9,:] - %[0-9,:]", sztime1, sztime2); //-------非本段作者--------------------------------------------------------------------------------------------------- sscanf("2006:03:18-2006:04:18","%[^-]-%s",sztime1,sztime2); 描述:%[^-]匹配到‘-’默認(rèn)為存到sztime1的字符串“2006:03:18”加空格符,所以%s會(huì)默認(rèn)輸入“-2006:04:18”到sztime2這也就是%s前面加‘-’的原因。輸出跟作者一樣,但更易懂、易讀。 //----------------------------------------------------------------------------------------------------end----------------- 在softmse (Jake) 的問題貼http://community.csd(去掉我)n.n(去掉我)et/Expert/topic/4843/4843294.xml?temp=.4321558中 ,給出了一個(gè)很cool的sscanf用例,而后通過學(xué)習(xí),發(fā)現(xiàn)sscanf真棒,現(xiàn)做一總結(jié)。 原問題: iios/12DDWDFF@122 獲取/和@之間的字符串怎么做 C程序里面有什么函數(shù)嗎? 代碼: #include <stdio.h> int main() { const char* s = "iios/12DDWDFF@122"; char buf[20]; sscanf( s, "%*[^/]/%[^@]", buf ); printf( "%s\n", buf ); return 0; } 結(jié)果為:12DDWDFF

    總結(jié)

    以上是生活随笔為你收集整理的%d 跟%i 的区别以及scanf和sscanf的用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。