首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言溫度轉換:華氏轉攝氏與 scanf 陷阱深度解析

     編輯:關於C語言

C語言溫度轉換:華氏轉攝氏與 scanf 陷阱深度解析

華氏溫度轉攝氏溫度公式:C = 5 × (F - 32) / 9。看似簡單的程式,卻藏著 **scanf 格式字串陷阱**與**整數除法精度丟失**兩大經典坑點。

錯誤示範:scanf 格式字串包含換行

#include <stdio.h>

int main() {
    double c, f;
    printf("請輸入華氏溫度: ");
    scanf("%lf\n", &f);  // 錯誤:格式字串含 \n
    c = 5 * (f - 32) / 9;
    printf("f=%lf\nc=%lf\n", f, c);
    return 0;
}

現象:程式「卡住」,必須輸入多行非空白字元才會繼續。

原因:scanf 格式字串中的空白字元(含 \n、空格、Tab)意味著**「讀取並丟棄任意數量的空白字元,直到遇到非空白字元」**。輸入數字後按 Enter,\n 讓 scanf 繼續等待下一個非空白字元,導致看似死循環。

正確寫法

#include <stdio.h>

int main() {
    double c, f;
    printf("請輸入華氏溫度: ");
    scanf("%lf", &f);  // 正確:無尾隨空白
    c = 5 * (f - 32) / 9.0;  // 關鍵:9.0 強制浮點除法
    printf("f=%lf\nc=%lf\n", f, c);
    return 0;
}

第二大坑:整數除法截斷

c = 5 * (f - 32) / 9;   // 錯誤:5、9 為 int,整數除法
c = 5 * (f - 32) / 9.0; // 正確:9.0 為 double,浮點除法

雖然 f 是 double,但 5 * (f - 32) 結果為 double,除以 9 (int) 會隱式轉換為 double,**實際上此處不會整數除法**。但若寫成 5 / 9 * (f - 32),5/9 先執行整數除法得 0,結果全錯。**最佳實踐:常數參與浮點運算時全部加 .0**。

scanf 格式字串空白字元規則總結

格式字串行為建議
"%d"跳過前導空白,讀取整數,停留在下一字元標準用法
"%d\n"讀取整數後,繼續吞噬後續所有空白(含換行),等待非空白**極少使用**,易卡住
" %d"前導空白強制跳過(%d 本身就會跳過),效果相同冗餘但無害
"%c"**不跳過空白**,直接讀取下一字元(含空格、換行)需配合 " %c" 跳過空白

健壯的輸入處理模板

double read_double(const char *prompt) {
    double val;
    int ret;
    while (1) {
        printf("%s", prompt);
        ret = scanf("%lf", &val);
        if (ret == 1) break;  // 成功讀取
        if (ret == EOF) exit(1); // 檔案結束
        // ret == 0:輸入不匹配,清空緩衝區
        scanf("%*[^\n]");  // 丟棄至換行
        scanf("%*c");      // 丟棄換行
        puts("輸入無效,請重新輸入數字。");
    }
    return val;
}

總結

  1. scanf 格式字串尾部勿加空白字元(含 \n),除非你確定要「吞噬後續所有空白」。
  2. 浮點運算常數加 .0,避免整數除法陷阱。
  3. 檢查 scanf 返回值,處理非數字輸入,清空緩衝區防止無限迴圈。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved