scanf函數詳細講解


(1)簡介

scanf函數是c語言當中非常重要的格式化輸入函數

其函數原型為:int scanf(const char *format, ...);

其函數返回值:成功格式化解析的個數

其調用格式為:scanf("<格式化字符串>", <參量表>);

(2)轉換說明:

轉換格式為:%[*][寬度][類型長度]類型

除了最后的類型之外都是可選的字段

轉換修飾符
修飾符 意義
* 滯后賦值;示例:"%*d"
digit(s) z最大字段寬度;在達到最大字段寬度或者遇到第一個空白字符時(不管哪個先發生都一樣)停止對輸入項的讀取;示例:"%10s"
hh b把整數讀作signed char或unsigned char;示例:"%hhd" "%hhu"
ll b把整數讀作long long或unsigned long long(c99);示例:"%lld" "%llu"
h,l或L "%hd"和"%hi"指示該值將會儲存在一個short int中。"%ho"、"%hx"和"%hu"指示該值將會儲存在一個unsigned short int中。"%ld"和"%li"指示該值將會儲存在一個long中。"%lo"、"%lx"和"%lu"指示該值將會儲存在一個unsigned long中。"%le"、"%lf"和"%lg"指示該值以double類型儲存。將L(而非l)與e、f和g一起使用指示該值以long double類型儲存。如果沒有這些修飾符,d、i、o和x指示int類型,而e、f和g指示float類型;

 

轉換說明符
轉換說明符 意義
%c 把輸入解釋稱一個字符
%d 把輸入解釋稱一個有符號十進制整數
%e,%f,%g,%a 把輸入解釋稱一個浮點數(%a是c99標准)
%E,%F,%G,%A 把輸入解釋稱一個浮點數(%A是c99標准)
%i 把輸入解釋稱一個有符號十進制整數
%o 把輸入解釋稱一個有符號八進制整數
%p 把輸入解釋稱一個指針(一個地址)
%s 把輸入解釋稱一個字符串,輸入內容以第一個非空白字符作為開始,並且包含直到下一個空白字符的全部字符
%u 把輸入解釋稱一個無符號十進制整數
%x,%X 把輸入解釋稱一個無符號十六進制整數
[] 字符集合

 

 

(3)高級用法:

網上已經有很多博客將scanf的常用方法說的非常詳細了,本篇博客不再詳細介紹。

1。捕獲規則

在出現一個轉換說明符時,scanf函數會忽略前面的所有空白字符(除了%c),然后再捕獲相應的數據類型,一直到最大長度或者出現空白字符

 

scanf("%d,%d", &a, &b); 

 

允許的輸入格式為:1,2\n;1,  2\n;1,\n2\n;

不允許的輸入格式:1 ,2\n;   \n1,2\n; 1,2\n;  

2。%[] 字符集合

這個算scanf函數中比較高級一點的用法

[]里面填寫需要捕獲的字符集合,例如

char buf[20];

scanf("%[abc]", buf);  //輸入abcdabcd123, buf內容為abc

scanf函數匹配[]中的所有字符,直到找到一個非[]中的字符

[]中也可以填寫字符范圍,例如

[a-z] //捕獲包括字符從a到z的所有字符,直到找到一個非a-z的字符

[a-zA-Z] //捕獲所有字母

[0-9] //捕獲所有數字

[a-zA-Z0-9]捕獲所有字母和數字

[a-zA-Z0-9!]捕獲所有字母和數字並且捕獲!(感嘆號)

[]中如果第一字符為^符號則表示出現[]中的內容則停止捕獲,例如

[^a-zA-Z]捕獲非字母

[^0-9]捕獲非數字

3。scanf中的空格和\n

scanf中的空格的作用不僅僅是捕獲一個空格,它表示捕獲所有空白字符(空格,換行,制表符等)直到出現一個非空白字符(\n一樣),例如

我們想接受一個ip:端口的輸入

需要接受的輸入格式為:ip:端口,ip: 端口,ip : 端口,ip\n:\n端口

如果代碼為scanf("%d.%d.%d.%d:%d", &ip[0], &ip[1], &ip[2], &ip[3], &port);

則只能捕獲的格式:ip:端口,ip: 端口,ip:\n端口

如果我們將代碼改為scanf("%d.%d.%d.%d :%d", &ip[0], &ip[1], &ip[2], &ip[3], &port); // : 前面多了一個空格

則可以捕獲上述所有情況

4。scanf中的混合輸入字符和數字

在scanf當中混合輸入字符和數字是一個比較煩人的問題

如果我們直接編寫代碼為

 1 #include <stdio.h>
 2 
 3 int main() {
 4     char ch;
 5     int num;
 6 
 7     while(scanf("%c%d", &ch, &num) == 2) {
 8         printf("*%c*, *%d*\n", ch, num);
 9     }
10     return 0;
11 }

 

第一次scanf("%c%d");沒有任何問題

第二次scanf("%c%d");字符會將上一次的\n給解析進來,就會出現了問題

解決方案1:

#include <stdio.h>

int main() {
    char ch;
    int num;

    while(scanf("%c%d", &ch, &num) == 2) {
        printf("*%c*, *%d*\n", ch, num);

        while(getchar() != '\n'); //清除上次輸入殘留的\n
    }
    return 0;
}

解決方案2:

#include <stdio.h>

int main() {
    char ch;
    int num;

    while(scanf(" %c%d", &ch, &num) == 2) { //前面加一個空格忽略所有空白字符
        printf("*%c*, *%d*\n", ch, num);
    }
    return 0;
}

未定義的方案(官方文檔未定義,勿用):

#include <stdio.h>

int main() {
    char ch;
    int num;

    while(scanf("%c%d", &ch, &num) == 2) {
        printf("*%c*, *%d*\n", ch, num);
        fflush(stdin); //flush標准輸入流
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM