代碼是寫不完的,函數(shù)也不可能全部掌握,畢竟一個項目也不可能把所有的函數(shù)用一遍,但是工作當中的項目都有一個共同點,就是像上面這樣,至少會有一個輸入,也至少會有一個輸出,中間的黑盒子是用戶不需要關(guān)系的,那么作為工程師我們做的就是實現(xiàn)這個黑盒子,但是要實現(xiàn)這個黑盒子,那么我們必須明確我們的輸入是什么,換言之就是明確用戶的需求,哈哈,說了這么一大堆,其實就是引入一個可以用來提供用戶輸入的函數(shù)接口scanf而已。
概述
當我們剛開始C學習編程的時候,可能第一個代碼是printf,但是下一個代碼可能就會用到scanf了,因為在我們還不明白fgets,fread,read……等一系列其他的函數(shù)接口的時候,scanf就比較有用了,可以滿足我們大多數(shù)的輸入操作請求。
在Ubuntu下man scanf,你會看到如下內(nèi)容
scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf - input format conversion
SYNOPSIS
#include <stdio.h>
int scanf(const char *format, ...);
我們首先從基本的用法入手來看scanf函數(shù):那么什么是基本用法呢?
就是認識函數(shù)接口的三要素: 功能,參數(shù),返回值。
功能:格式化輸入,====>依據(jù)你的輸入存放到指定的變量當中
參數(shù):注意類型是 char *format, 再除以參數(shù) … 是可變參數(shù)
這個解釋有兩點需要注意:
1、char *format指針,對應一個的字符串,底層實現(xiàn)是字符串解析
2、參數(shù)是可變的,至少一個,那么也闊以同時輸入多個,且必須是地址
3、在終端上的輸入格式需要和char *format的格式一樣
返回值:
成功:正確按指定格式輸入變量的個數(shù);,小于等于最大的輸入項個數(shù)
失敗:返回0
一般用法:
scanf()函數(shù)的一般格式為:scanf("格式字符串",輸入項首地址表)
scanf的格式控制的一般形式為:%[寬度]類型字符
"類型字符":
d -- 輸入十進制整數(shù) 、o -- 輸入八進制整數(shù) 、x -- 輸入十六進制整數(shù) 、u -- 輸入無符號十進制整數(shù) f或e -- 輸入實型數(shù)(用小數(shù)形式或指數(shù)形式) 、c -- 輸入單個字符 、s -- 輸入字符串
scanf("輸入控制符", 輸入?yún)?shù));
功能:將從鍵盤輸入的字符轉(zhuǎn)化為“輸入控制符”所規(guī)定格式的數(shù)據(jù),然后存入以輸入?yún)?shù)的值為地址的變量中。
測試代碼1: 數(shù)值型和字符型數(shù)據(jù)的輸入
#include<stdio.h>
int main(int argc, const char *argv[])
{
int x;
char ch;
printf("please input a number:");
scanf("%d",&x); //&x 表示變量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.
測試代碼2:字符串類型數(shù)據(jù)的輸入
#include<stdio.h>
int main(int argc, const char *argv[])
{
int x;
char str[16] = {0}; //數(shù)組的大小合理分配 2^n次方分配比較好
printf("please input 1 number:");
scanf("%d",&x); //數(shù)值型的數(shù)據(jù)需要取地址
printf("please input string :");
scanf("%s",str); //注意,這里不需要取地址,str本身就是地址
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.
測試代碼3:數(shù)字和字符的格式化輸入---注意字符串的長度被截取了
#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
"寬度"
表示輸入讀入字符和整型的長度表示截取相應寬度的數(shù)字賦給后面列表中的相應變量;其余的自動舍棄。
對于字符串,則可以用來截取對于長度的數(shù)據(jù)存放到對應的buf當中,其他舍去。
scanf("%2d%3d",&a, &b);如果輸入為12345則將12賦給a,將45賦給b;scanf("%2c%3c",&a, &b);如果輸入為12345則將'1'賦給a,將'3'賦給b
scanf("%8s",str1);如果輸入為”helloworld”,則將“hellowor”賦值給str1,其他舍棄
測試記錄4:數(shù)值型數(shù)據(jù)和字符串數(shù)據(jù)的混合輸入
#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;
}
測試結(jié)果; 在輸入的時候一定不要忘記你格式化的那個空格,否則會報錯
正常輸入:
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.
測試記錄5:典型錯誤測試實錄
#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 :.
在使用的時候一定要注意輸入格式的提示,或者自己在軟件層面做容錯的處理,否則很容易導致不良的用戶體驗,你要明白,用戶是怎么操作的? 答:隨便操作,隨意很多問題要在設計的時候就考慮到。
以上是 scanf 的最簡單用法,也是最常用、最基本、最重要的用法。