C語言scanf函數用法
時間:2019-05-23 來源:華清遠見

代碼是(shi)寫不完的(de)(de)(de),函數(shu)也不可(ke)能全部掌握,畢竟一(yi)(yi)個(ge)(ge)(ge)項目(mu)也不可(ke)能把所有的(de)(de)(de)函數(shu)用(yong)(yong)一(yi)(yi)遍,但(dan)是(shi)工作當中的(de)(de)(de)項目(mu)都有一(yi)(yi)個(ge)(ge)(ge)共(gong)同點,就(jiu)(jiu)是(shi)像(xiang)上面這(zhe)樣,至少(shao)會(hui)(hui)有一(yi)(yi)個(ge)(ge)(ge)輸(shu)入(ru)(ru),也至少(shao)會(hui)(hui)有一(yi)(yi)個(ge)(ge)(ge)輸(shu)出,中間的(de)(de)(de)黑盒子是(shi)用(yong)(yong)戶(hu)不需要關系的(de)(de)(de),那么(me)(me)(me)作為工程師我(wo)們做(zuo)的(de)(de)(de)就(jiu)(jiu)是(shi)實現(xian)這(zhe)個(ge)(ge)(ge)黑盒子,但(dan)是(shi)要實現(xian)這(zhe)個(ge)(ge)(ge)黑盒子,那么(me)(me)(me)我(wo)們必須(xu)明確我(wo)們的(de)(de)(de)輸(shu)入(ru)(ru)是(shi)什么(me)(me)(me),換(huan)言之就(jiu)(jiu)是(shi)明確用(yong)(yong)戶(hu)的(de)(de)(de)需求(qiu),哈(ha)哈(ha),說了(le)這(zhe)么(me)(me)(me)一(yi)(yi)大堆,其實就(jiu)(jiu)是(shi)引(yin)入(ru)(ru)一(yi)(yi)個(ge)(ge)(ge)可(ke)以用(yong)(yong)來提供用(yong)(yong)戶(hu)輸(shu)入(ru)(ru)的(de)(de)(de)函數(shu)接口scanf而已。
概述
當我(wo)們(men)剛開始C學習編(bian)程的時候(hou),可能第一(yi)個(ge)代(dai)碼(ma)是(shi)printf,但是(shi)下一(yi)個(ge)代(dai)碼(ma)可能就會(hui)用到scanf了,因(yin)為(wei)在(zai)我(wo)們(men)還不(bu)明(ming)白fgets,fread,read……等一(yi)系列其他的函數接(jie)口的時候(hou),scanf就比較有用了,可以滿足我(wo)們(men)大多數的輸入操作請(qing)求。
在Ubuntu下man scanf,你會看到(dao)如下內容
scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf - input format conversion
SYNOPSIS
#include <stdio.h>
int scanf(const char *format, ...);
我們首先(xian)從基本(ben)的用法(fa)(fa)入手來(lai)看scanf函數:那么什么是基本(ben)用法(fa)(fa)呢?
就是認識(shi)函數(shu)接(jie)口(kou)的三要(yao)素: 功能,參數(shu),返回值(zhi)。
功能:格(ge)式化輸(shu)入(ru),====>依據你的輸(shu)入(ru)存放到指定的變(bian)量當中(zhong)
參(can)數:注意類型(xing)是 char *format, 再除以(yi)參(can)數 … 是可(ke)變(bian)參(can)數
這個解釋有兩點需要注意:
1、char *format指(zhi)針,對(dui)應一個(ge)的(de)字(zi)符(fu)串,底層實現是(shi)字(zi)符(fu)串解(jie)析
2、參數(shu)是可變的,至(zhi)少一個,那么(me)也闊以同時(shi)輸入多個,且必須是地址
3、在終端上的(de)輸入格(ge)式(shi)需要和char *format的(de)格(ge)式(shi)一樣(yang)
返回值:
成功:正確按(an)指定格式輸(shu)入變量的(de)(de)個數;,小于(yu)等于(yu)最大的(de)(de)輸(shu)入項個數
失(shi)敗:返回0
一般用法:
scanf()函數的(de)一(yi)般格(ge)式(shi)為:scanf("格(ge)式(shi)字符串",輸(shu)入(ru)項首地址表)
scanf的(de)格式控制的(de)一般形式為:%[寬度]類型字符
"類型字符":
d -- 輸(shu)入(ru)(ru)十(shi)進(jin)制整數 、o -- 輸(shu)入(ru)(ru)八進(jin)制整數 、x -- 輸(shu)入(ru)(ru)十(shi)六進(jin)制整數 、u -- 輸(shu)入(ru)(ru)無(wu)符號(hao)十(shi)進(jin)制整數 f或(huo)e -- 輸(shu)入(ru)(ru)實(shi)型(xing)數(用小數形式或(huo)指數形式) 、c -- 輸(shu)入(ru)(ru)單個字符 、s -- 輸(shu)入(ru)(ru)字符串(chuan)
scanf("輸入控制符(fu)", 輸入參數(shu));
功能:將(jiang)從鍵盤輸(shu)(shu)入(ru)的(de)(de)字符(fu)(fu)轉(zhuan)化為(wei)“輸(shu)(shu)入(ru)控制符(fu)(fu)”所(suo)規定格(ge)式的(de)(de)數(shu)據,然(ran)后存入(ru)以輸(shu)(shu)入(ru)參數(shu)的(de)(de)值為(wei)地址的(de)(de)變量中。
測試(shi)代(dai)碼(ma)1: 數(shu)(shu)值型(xing)和字符型(xing)數(shu)(shu)據(ju)的(de)輸入
#include<stdio.h>
int main(int argc, const char *argv[])
{
int x;
char ch;
printf("please input a number:");
scanf("%d",&x); //&x 表示變(bian)量(liang)x 的地址,&是取地址符
printf("x = %d.\n",x);
printf("please input a char:");
scanf("%c",&ch);
printf("ch = %c.\n",ch);
return 0;
}
~
測試記錄:
linux@ubuntu:~$ gcc test.c
linux@ubuntu:~$ ./a.out
please input a number:99
x = 99.
please input a char: a
ch = a.
測試(shi)代(dai)碼2:字(zi)符串類型數據的輸入
#include<stdio.h>
int main(int argc, const char *argv[])
{
int x;
char str[16] = {0}; //數組的大(da)小合(he)理分(fen)配 2^n次方分(fen)配比較好
printf("please input 1 number:");
scanf("%d",&x); //數值型的數據(ju)需要取地址
printf("please input string :");
scanf("%s",str); //注意,這里不需(xu)要(yao)取地址(zhi),str本(ben)身就(jiu)是地址(zhi)
printf("x = %d.\n",x);
printf("str :%s.\n",str);
return 0;
}
測試記錄:
linux@ubuntu:~$ gcc test.c
linux@ubuntu:~$ ./a.out
please input 1 number:10
please input string :helloworld
x = 10.
str :helloworld.
測試代(dai)碼3:數字和(he)字符的格式(shi)化輸入---注意字符串的長度(du)被(bei)截取了
#include<stdio.h>
int main(int argc, const char *argv[])
{
int x;
char str1[16] = {0};
printf("please input (eg:10 haha):");
scanf("%8d %8s",&x,str1);
printf("x=%d str1:%s\n",x,str1);
return 0;
}
~
測試記錄:
linux@ubuntu:~$ gcc test.c
linux@ubuntu:~$ ./a.out
please input (eg:10 haha):5 helloworld
x=5 str1:hellowor
"寬度(du)"
表示輸入讀(du)入字符和(he)整型的長度表示截取(qu)相應寬度的數字賦給(gei)后面(mian)列(lie)表中的相應變量;其余(yu)的自(zi)動舍棄(qi)。
對(dui)于字(zi)符串,則(ze)可以用來截取對(dui)于長度的數據存(cun)放到對(dui)應的buf當中(zhong),其他舍去。
scanf("%2d%3d",&a, &b);如(ru)果輸入(ru)為(wei)12345則將(jiang)12賦(fu)給a,將(jiang)45賦(fu)給b;scanf("%2c%3c",&a, &b);如(ru)果輸入(ru)為(wei)12345則將(jiang)'1'賦(fu)給a,將(jiang)'3'賦(fu)給b
scanf("%8s",str1);如果輸入為(wei)”helloworld”,則將“hellowor”賦值給str1,其他舍棄
測試記錄4:數(shu)值型數(shu)據(ju)和字符串數(shu)據(ju)的混合(he)輸入(ru)
#include<stdio.h>
int main(int argc, const char *argv[])
{
int retval;
int x;
float y;
char str1[16] = {0},str2[16] = {0};
printf("please input (eg:10 haha 20.1 gaga):");
retval = scanf("%d %s %f %s",&x,str1,&y,str2);
printf("retval :%d.\n",retval);
printf("x = %d.y = %f.\n",x,y);
printf("str1 :%s\nstr2 :%s.\n",str1,str2);
return 0;
}
測試結果; 在輸入的時(shi)候一定不要忘(wang)記你格(ge)式化的那個(ge)空格(ge),否則會報錯(cuo)
正常輸入:
linux@ubuntu:~$ ./a.out
please input (eg:10 haha 20.1 gaga):30 GREE 99 hqyj
retval :4.
x = 30.y = 99.000000.
str1 :GREE
str2 :hqyj.
測(ce)試(shi)記錄5:典型(xing)錯誤測(ce)試(shi)實錄
#include<stdio.h>
int main(int argc, const char *argv[])
{
int retval;
int x;
float y;
char str1[16] = {0},str2[16] = {0};
printf("please input (eg:x = 10 str1 = haha y = 20.1 str2 = gaga):");
retval = scanf("x = %d str1 = %s y = %f str2 = %s",&x,str1,&y,str2);
printf("retval :%d.\n",retval);
printf("x = %d.y = %f.\n",x,y);
printf("str1 :%s\nstr2 :%s.\n",str1,str2);
return 0;
}
錯誤輸入:
linux@ubuntu:~$ gcc test.c
linux@ubuntu:~$ ./a.out
please input (eg:x = 10 str1 = haha y = 20.1 str2 = gaga):88 haha 99 gaga
retval :0.
x = 0.y = 0.000000.
str1 :
str2 :.
在使用的時(shi)候(hou)(hou)一(yi)定要(yao)注(zhu)意(yi)輸入格式的提示,或者自己在軟件層面做容錯(cuo)的處理,否(fou)則很容易導致不良的用戶體驗,你(ni)要(yao)明白,用戶是怎么操作的? 答:隨便操作,隨意(yi)很多(duo)問題要(yao)在設計的時(shi)候(hou)(hou)就(jiu)考慮到。
以上是 scanf 的最(zui)簡單用法,也是最(zui)常用、最(zui)基本、最(zui)重(zhong)要的用法。

