scanf和緩衝區的一切

<!--從緩衝區到輸入列表-->

程序獲取輸入時的過程比咱們想象的複雜  咱們考慮一個簡單粗暴完整的程序
 編程

#include <stdio.h>
int main(){
    int n;
    scanf("%d", &n);
    printf("%d\n", n);
    return 0;
}

 

程序運行到scanf()時會中止  請求外界輸入

也許你輸入了125而後回車了

但事實上 你從鍵盤上輸入的是字符'1''2''5'  還有換行符'\n'  (由於你鍵入了回車)

在你按回車鍵以前  字符'1''2''5'都處於一個叫作緩衝區的位置裏函數

回車鍵是特殊的  它先將字符'\n'添加到緩衝區 隨後便清除緩衝區  將其中的全部字符發送到一個叫作輸入列表的地方code

scanf函數以及其餘標準輸入函數便會馬上從輸入列表中獲取內容get

 

上述程序按照%d的規則從輸入列表中獲取字符  它獲取了'1''2''5'  而且將其轉變爲整數125  存入了變量n中

對於那些從輸人列表中獲取輸入的函數  它們並不知道什麼是整數  由於整數是編程中的概念  而不管是緩衝區仍是輸入列表  其中只有字符  因此「獲取整數」只是從結果上看的

再多說一點  因爲每一個字符是一個字節  因此便有了字節流這個術語

咱們繼續考慮上面的程序  你要求scanf獲取一個整數到n中  它完成了

可是並無結束  由於輸入列表並不乾淨  回車符'\n'仍然留在輸入列表中博客

 

因此若是程序以下
 io

#include <stdio.h>
int main(){
    int n;
    char ch;
    scanf("%d", &n);
    printf("%d", n);
    scanf("%c", &ch);    //! 不會中止等待
    printf("%c", ch);
    return 0;
}

咱們仍然鍵入125而且回車  那麼第二個scanf將不會給你輸入的機會  由於緩衝區中剩餘的'\n'已經足夠填飽ch的肚子
 變量

 

 

再考慮下一個程序
 請求

#include <stdio.h>
int main(){
    int n;
    char ch1, ch2;
    scanf("%c%d%c", &ch1, &n, &ch2);
    printf("ch1 = %c\n", ch1);
    printf("n = %d\n", n);
    printf("ch2 = %c\n", ch2);
    return 0;
}

咱們的鍵入仍然是125回車

結果是ch1 == '1'  n == 25  ch2 == '\n'


格式說明符對於scanf是十分重要的   它即是「規則」 告訴scanf如何從輸入列表中獲取字符 而且如何作轉換

時刻記住輸入列表中的內容全是字符  規律就會十分容易

還有須要注意的是  儘管輸入列表中的內容都是字符  可是字符還有分類  好比空白符  數字字符  字母字符等
 程序

 

%d 忽略前置空白符  獲取連續數字字符 直到趕上非數字字符或者輸入列表尾爲止

可是若是忽略到空白符以後遇到的時非數字字符 那麼就直接結束

獲取前的輸入列表

' '  ' '  ' '  'k'  'o'  'w'  '\n'

獲取後

'k'  'o'  'w'  '\n'di

 

%f 這個比較複雜 可是咱們只要明白從什麼時候開始 到什麼時候爲止便可
假如輸入列表是這樣

' '  ' '  '2'  '.'  '5'  '.'  '2'  '1'  '4'  'f'  'g'  '\n'

那麼%f獲取後 列表變爲

'.'  '2'  '1'  '4'  'f'  'g'  '\n'

 

 

%c 直接獲取一個字符到目標變量 「看見什麼吃什麼」



因爲全部輸入函數都共享同一個輸入列表  因此在整數和字符的混合輸入中可能出錯

若是你不清楚在獲取一個整數之後的下一個獲取是否爲字符 加上下面的語句是最保險的

while(getchar() != '\n') continue;

它將清除輸入列表

 

 

 

 

儘管是寫給初學者的  也有點太累贅了

反正我是絕對耐不下性子讀完別人寫的這麼長的博客 (除非像我說得這麼清楚明白  呵呵噠)

相關文章
相關標籤/搜索