標準輸出 (stdout) 與標準錯誤 (stderr) 是兩條獨立的數據流。區分它們能讓「正常數據」與「錯誤訊息」分離,支援管道、重定向等 Unix 哲學工具鏈。
示例:讀取 GPS 數據文件轉 JSON,若遇非法經緯度需報錯但不污染 JSON 輸出。
#include <stdio.h>
int main() {
float lat, lon;
char info[80];
int started = 0;
puts("data[");
while (scanf("%f,%f,%79[^\n]", &lat, &lon, info) == 3) {
if (started) printf(",\n"); else started = 1;
if (lat < -90.0 || lat > 90.0) {
fprintf(stderr, "Invalid latitude: %f\n", lat); // 寫入 stderr
return 2;
}
if (lon < -180.0 || lon > 180.0) {
fprintf(stderr, "Invalid longitude: %f\n", lon);
return 2;
}
printf("{latitude:%f,longitude:%f,info:'%s'}", lat, lon, info);
}
puts("\n]");
return 0;
}
# 僅重定向 stdout 到文件,stderr 仍顯示在終端
$ ./gps_json < gpsdata.csv > output.json
Invalid latitude: 95.000000 # 這行出現在螢幕,不在 output.json
# 同時重定向 stderr
$ ./gps_json < gpsdata.csv > output.json 2> errors.log
# 合併 stdout 和 stderr
$ ./gps_json < gpsdata.csv > all.log 2>&1
# 或
$ ./gps_json < gpsdata.csv &> all.log
| 流 | 文件描述符 | 預設設備 | 典型用途 | C 函數 |
|---|---|---|---|---|
| stdin | 0 | 鍵盤 | 輸入數據 | scanf, fgets, fread |
| stdout | 1 | 終端 | 正常輸出 | printf, puts, fwrite |
| stderr | 2 | 終端 | 錯誤/診斷信息 | fprintf(stderr,...), perror |
fprintf(stderr, ...) 可將格式化錯誤信息發送到標準錯誤。perror("msg") 自動附加當前 errno 對應的系統錯誤字串。> (stdout)、2> (stderr)、&> (合併)、2>&1 (stderr 重定向到 stdout)。stderr;stdout 僅輸出結構化數據(JSON、CSV、純文本結果),便於管道處理。