2023年5月22日 星期一

C 語言 scanf() 讀取字串時遇到空白停止讀取問題

昨天在備課準備練習題時發現, scanf() 函式在讀取鍵盤輸入的字串時, 若字串內有空白, 則讀到第一個空白時就會停止 (例如輸入 'I love you' 只讀到 'I' 而已), 以至於沒有讀取完整的字串輸入, 例如下面這個範例, 想要從鍵盤讀取字串, 然後將字串中的空白以星號替換 : 

/* 從鍵盤輸入一個字串,利用指標將字串中的空白字元全部改成星號 */
#include <stdio.h>

void sp2star(char *);             /* 函數原型宣告 */

int main() {
  char str[20];
  printf("請輸入字串 => ");             /* 提示輸入字串 */
  int x=scanf("%s", str);                    /* 讀取鍵盤輸入的字串 */
  printf("\n輸入的字串: %s", str);    /* 顯示輸入的字串 */
  sp2star(str);                       /* 呼叫函式將字串中的空白以星號替換 */
  printf("\n結果字串 => %s\n", str);  /* 印出結果字串 */
  }

void sp2star(char *s) {               /* 傳入指標 */
  while(*s != '\0') {                    /* 掃描字串中的字元直到結尾 */ 
    if (*s == ' ') {*s='*';}            /* 空白字元用星號取代 */ 
    s++;                                    /* 指標增量1 */ 
    }
  }

將這個程式複製到下面這個線上 C 編譯器執行, 結果發現輸入的 'I love you' 字串只讀到第一個字元 'I' 而已 : 


結果如下 : 

請輸入字串 => I love you!

輸入的字串: I
結果字串 => I

從輸入的字串為 I 可知 scanf() 並未讀進整個字串, 而是遇到第一個空白時就停止讀取了, 解決辦法是 scanf() 的第一個參數不要用 %s, 改用正規式 [^\n], 表示讀取所有不是跳行的字元, 這樣就不會遇到空白就停止了, 參考 :


修正後的程式如下 :

/* 從鍵盤輸入一個字串,利用指標將字串中的空白字元全部改成星號 */
#include <stdio.h>

void sp2star(char *);             /* 函數原型宣告 */

int main() {
  char str[20];
  printf("請輸入字串 => ");           /* 提示輸入字串 */
  int x=scanf("%[^\n]", str);         /* [^\n]=讀取不是跳行的所有字元 */
  printf("\n輸入的字串: %s", str);    /* 顯示輸入的字串 */
  sp2star(str);                       /* 呼叫函式將字串中的空白以星號替換 */
  printf("\n結果字串 => %s\n", str);  /* 印出結果字串 */
  }

void sp2star(char *s) {               /* 傳入指標 */
  while(*s != '\0') {                 /* 掃描字串中的字元直到結尾 */ 
    if (*s == ' ') {*s='*';}          /* 空白字元用星號取代 */ 
    s++;                              /* 指標增量1 */ 
    }
  }

結果如下 : 

輸入字串 => I love you!

輸入的字串: I love you!
結果字串 => I*love*you!

這樣就正確了. 

沒有留言:

張貼留言