詳解printf重定向到檔案中,列印日誌的實現

2021-08-20 14:02:38 字數 2589 閱讀 2860

printf是將資訊列印到終端,但是有時當我們需要列印的資訊比較多時,終端無法將所有資訊都能夠保留在螢幕上,這樣我們就不能在終端獲取我們想要的資訊了,重定向很好的幫我們解決了這個問題,下面我就通過重定向printf將列印資訊列印到檔案中,這也相當於乙個列印日誌。

列印日誌的功能是這樣的,日誌檔案命名為yyyymmdd.log,例如20180530.log,預設儲存在與執行程式同一目錄下;

若連續記錄,則在每天0點重新生成當天日誌;若程式執行時已有當天的日誌,新的除錯資訊追加到該日誌檔案末。

建立乙個執行緒,用來檢測時間,當過了24點進入新的一天時,已追加的方式重新建立乙個日誌檔案 ,這樣就可以將列印資訊都記錄到日誌檔案中,當然前提是標準輸出已經重定向到檔案了,這才是本文的重點。

因為標準輸入輸出是行快取,而我們的檔案屬於全快取,所以我們需要將快取區設定為無緩衝直接寫到檔案中,使用setbuf函式設定快取區快取為無快取,使用dup2重定向標準輸出為檔案描述符

setvbuf(stdout, null, _iolbf, 0) != 0;

dup2(file_fd, stdout_fileno)

下面附上整個專案**,該**執行在多程序中

#include #include #include #include #include #include #include #include #include "type_def.h"

static void *log_thread(void *arg);

static void setsystime(char *timestr);

static void child_process(void);

int main(int argc, const char *argv)

else if (0 == pid)

else

while (1)

}return 0;

}/** @fn child_process

* @brief 程序處理函式

* */

static void child_process(void)

while (1)

return;

}/** @fn log_thread

* @brief 執行緒處理函式,用來改變printf的重定向,每一天建立乙個日誌檔案

* * @param arg 沒有使用

* * @return 返回執行緒退出的狀態值。可通過pthread_join函式獲得

*/static void *log_thread(void *arg)

; // 日誌檔案的描述符陣列

char log_name[16] = ; // 日誌檔名

uint32 i = 0, j = 0;

#if 1

/* 設定快取區為無快取直接向流寫入資料 */

fflush(stdout);

if (setvbuf(stdout, null, _iolbf, 0) != 0)

#endif

while (1)

/* 如果當前日期不等於yesterday,代表現在已經是新的一天,建立新的日誌檔案 */

if (yesterday != p_time->tm_mday)

if (-1 == dup2(file_fd[i], stdout_fileno))

close(file_fd[j]);

} sleep(1);

}err_exit:

if (file_fd[0] > 0)

if (file_fd[1] > 0)

pthread_exit(0);

}/** @fn setsystime

* @brief 用來設定系統的時間

* * @param timestr[in] 指定設定時間

* */

static void setsystime(char *timestr)

; struct tm localtime = ;

uint32 year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;

sscanf(timestr, "%d.%d.%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);

localtime.tm_sec = second;

localtime.tm_min = minute;

localtime.tm_hour = hour;

localtime.tm_mday = day;

localtime.tm_mon = month - 1;

localtime.tm_year = year - 1900;

/* 將struct tm結構體的時間轉換成2023年1月1日以來逝去時間的秒數; */

tv.tv_sec = mktime(&localtime);

tv.tv_usec = 0;

settimeofday(&tv, null);

return;

}

重定向printf到串列埠

參考鏈結 stm32 hal庫學習 三 adc取樣以及printf的使用 stm32cubeide 二 printf重定向設定 stm32cubeide實現printf重定向輸出到串列埠 在main.c檔案中插入如下 user code begin 0 include stdio.h ifdef g...

VC程式重定向printf到console視窗

本方法簡單易用,適用於vc6 vc.net2003 假定你建立的vc應用程式叫做imagefilter,那麼只需新增如下 即可 1 開啟imagefilter.cpp檔案,增加 include include allocconsole hcrt open osfhandle long getstdh...

Keil重定向printf到串列埠UART輸出

下面是我搜尋到的可以借鑑的討論 我的評述 評述 在乙個晶元系統裡,uart的驅動是廠商自己寫好的,那他們是怎麼關聯printf到uart的呢?有人說,printf最終是呼叫了putchar,我搜尋了原始碼,沒有這個函式,估計是開發工具,像keilc u3,裡面已經整合了putchar。於是我奇怪,這...