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。於是我奇怪,這...