關於LINUX C庫函式 中的 fprintf

2021-06-27 08:29:19 字數 3873 閱讀 1412

初學linux c庫,能見到它的原型如下:

int fprintf(file*stream,const char *format,...)

查程式例時,見到如下呼叫:

fprint(stderr,"cannot open output file.\n");

通常是指程式輸入或輸出的乙個連續的位元組序列,裝置(例如滑鼠、鍵盤、磁碟、螢幕、數據機和印表機)的輸入和輸出都是用流來處理的,在c語言中,所有的流均以檔案的形式出現——不一定是物理磁碟檔案,還可以是對應於某個輸入/輸出源的邏輯檔案。c語言提供了5種標準的流,你的程式在任何時候都可以使用它們,並且不必開啟或者關閉它們。(以下列出了這5種標準的流。

名稱 描述 

例子stdin 

標準輸入 

鍵盤stdout 

標準輸出 

螢幕stderr 

標準錯誤 

螢幕stdprn 

標準印表機 

lpt1埠

stdaux 

標準序列裝置 

com1埠

其中,stdprn和stdaux並不是總是預先定義好的,因為lpt1和com1埠在某些作業系統中是沒有意義的,而stdin,stdout和 stderr 總是預先定義好的

。此外stdin並不一定來自鍵盤,stdout也並不一定顯示在螢幕上,他們都可以是重定向到磁碟檔案或其他裝置上。我們在標頭檔案stdio.h中可以找到stdin,stdout和stderr的定義如下:

extern struct _io_file *stdin;

extern struct _io_file *stdout;

extern struct _io_file *stderr;

在使用fprintf()函式的時候,通常我們可以設第乙個引數為stdout或者stderr,列印出錯除錯資訊的時候則推薦使用stderr而不是stdout(當輸出的資訊是錯誤反饋時),

這是一種慣例,同時也由於核心在處理stdout和stderr時優先順序不一樣,後者的優先順序要高一些,因此有時候如果程式異常退出時,stderr能得到輸出,而stdout就不行。

printf(...)實際上相當於fprintf(stdout,...),這也是我們為什麼不推薦使用它的原因。在輸出除錯資訊的時候,我們推薦使用fprintf(stderr,...),

或者使用某個指定的檔案流

fprintf(some_stream,...)。

那麼具體如何在必要的時候重定向fprintf()中的除錯資訊呢?來看看下面一些方法:

當除錯資訊的量比較大,需要一些時間或者其他輔助工具來搜尋過濾時,僅僅利用顯示螢幕來輸出除錯的資訊是不夠的,這是我們經常將這些資訊輸出到所謂的日誌檔案(log)中,之後再自己分析log檔案發現問題

利用shell的i/o重定向(這個就夠用了)

簡單的些log方法可以通過shell的i/o重定向機制來實現,比如下面的**:

#include

int main()

fprintf(stdout,"this is a standard output info!\n");

fprintf(stderr,"this is a standard error output info!\n");

return 0;

在預設條件下,編譯執行的結果總是列印資訊輸出在螢幕上:

$gcc fprint.c -o fprint

$./fprint

this is a standard output info!

this is a standard error output info!

這是因為預設情況下,shell所開啟的stdout和stderr裝置都是顯示螢幕。不過我們可以通過shell的重定向功能來將列印資訊寫到檔案中去。比如:

$./fprint>output.log【這個語法可以在c程式語言第二版書摘的輸入輸出章節可見,用於把輸出定向到檔案】

this is a standard error output info!

$cat output.log

this is a standard output info!

這樣,我們把stdout的輸出寫到了檔案output.log中,不過stderr的輸出還是在螢幕上。如何重定向stderr呢?著需要用到shell定義的檔案描述符。在shell下stdin,stdout和stderr的檔案描述符分別是0,1和2,我們可以用下面的方法重定向:

$./fprint>output.log2>error.log

$cat output.log

this is a standard output info!

$cat error.log

this is a standard error output info!

$./fprint>output.log2>&1

$cat output.log

this is a standard error output info!

this is a standard output info!

其中./fprint >output.log 2>error.log分別將stdout 和 stderr 的輸入寫到檔案output.log 和error.log中,而./fprint>output.log2>&1則表示將stderr的輸出追加到stdout的檔案output.log中(結果是output.log 中既有 stdout輸出 也有stderr輸出)。

一些常用的shell i/o 語法如下:

cmd > file 把 stdout 重定向到 file 檔案中

cmd>> file 把 stdout 重定向到 file檔案中(追加)

cmd1 > file 把 stdout 重定向到 file 檔案中

cmd> file2>&1 把stdout 和stderr 一起重定向到 file檔案中

cmd 2>file 把 stderr重定向到file 檔案中

cmd 2>>file 把 stderr重定向到file檔案中(追加)

cmd>>file2>&1 把 stderr和stdout 一起重定向到file 檔案中(追加)

在平時簡單的除錯中,我們可以靈活利用這些方法來快速得到log檔案。

用freopen()進行重定向

有時候我們要求在程式中能夠控制標準流的重定向,這是可以利用標準c庫函式freopen().

freopen()的函式原型如下:

file *freopen(const char *filename,)

下面的**用來測試用函式freopen()重定向stderr:

#include

int main()

if(freopen("err.log",w,stderr)==null)

fprintf(stderr,"error redirecting stderr\n");

fprintf(stdout,"this is a standard output info!\n");

fprintf(stderr,"this is a standard error output info!\n");

fclose(stderr);

return 0;

}其中我們用freopen()函式將stderr重定向到了"err.log"檔案,這樣的得到的記過如下:

$gcc print_log.c -o print_log

$./print_log

this is a standard output info!

$cat err.log

this is a standard error output info!

可見第八行列印到stderr的資訊被重定向到了err.log檔案中,而第七行stdout的列印星系則還是輸出到了螢幕上。

原文

linux C庫函式 二

linux c庫函式 二 2010年01月26日 b linux fopen fclose fread fwrite等函式 b b b clearerr 清除檔案流的錯誤旗標 相關函式 feof 表頭檔案 include 定義函式 void clearerr file stream 函式說明 cle...

linux C庫函式 二

linux c庫函式 二 2010年01月26日 b linux fopen fclose fread fwrite等函式 b b b clearerr 清除檔案流的錯誤旗標 相關函式 feof 表頭檔案 include 定義函式 void clearerr file stream 函式說明 cle...

linux C庫函式 三

linux c庫函式 三 2010年01月26日 fseek 移動檔案流的讀寫位置 相關函式 rewind,ftell,fgetpos,fsetpos,lseek 表頭檔案 include 定義函式 int fseek file stream,long offset,int whence 函式說明 ...