场景需求
开发软件或者进行其他编程工作时,软件可能会长时间运行,但是!一旦突然崩溃就让人一脸懵逼,此时,日志log的功能就体现出来了,如果在日常编程的时候,有同步编写日志模块的好习惯,那么后期进行调试或者bug修复就很容易定位问题所在,大大提高开发效率哦~
相关函数说明
A.获取工作目录路径
/** * @brief GetProgramDir 获取当前工作目录路径 * @return 路径 */ string GetProgramDir() { char FullPath[MAX_PATH]; // 声明路径 string strPath = ""; GetModuleFileNameA(NULL, FullPath, MAX_PATH); // 获取当前运行程序的绝对路径 strPath = (string)FullPath; // 转为string型 int pos = static_cast<int>(strPath.find_last_of('\\', strPath.length())); return strPath.substr(0, pos); // 返回当前文件夹,不带文件名 }
B.获取当前时间
/** * @brief GetCurrentTimeA 获取当前时间信息 * @return * 需要用到time.h和ctime */ string GetCurrentTimeA(tm in) { tm *ct = ∈ int year, month, day, hour, minute, second;// 年月日时分秒。 year = ct->tm_year + 1900; // 年份基础从1900开始的,所以要加上 month = ct->tm_mon + 1; // 月份是0-11,对应1-12月 day = ct->tm_mday; hour = ct->tm_hour; minute = ct->tm_min; second = ct->tm_sec; char temp[100]; // 创建字符数组。 sprintf(temp, "%04d-%02d-%02d %02d:%02d:%02d: ", year, month, day, hour, minute, second);// 时间信息合并。 string out(temp); // 转化为string型 return move(out); // 用move(string)速度快很多。 }
C.书写日志内容
/** * @brief WriteLog 写进日志 * @param msg 内容 * @return 状态码 */ int WriteLog(string msg) { struct tm *local; time_t t; t = time(NULL); local = localtime(&t); string dtime = GetCurrentTimeA(*local); ofstream outfile; outfile.open(GetProgramDir() + "\\" + "log.txt", ios::app); //文件的物理地址,文件的打开方式, 如果没有会自动创建 if (outfile.is_open()) { outfile << dtime << msg << "\n"; outfile.close(); return 0; } else { return 1; } }
可能遇到的问题
可能出现sprintf和localtime不安全的警告提示,vs2017反正会出现,这个没啥影响,直接屏蔽掉就行~
图1 警告提示
屏蔽方案:
项目设置->C/C++->预处理器->预处理器定义,加上_CRT_SECURE_NO_WARNINGS即可。
图2 解决方案
C++实现代码
#include <iostream> #include <fstream> #include <sstream> #include <time.h> #include <ctime> #include <Windows.h> using namespace std; string GetProgramDir(); string GetCurrentTimeA(tm in); int WriteLog(string msg); int main(void) { WriteLog("ready!!!!"); Sleep(500); WriteLog("go!!!!"); Sleep(500); WriteLog("yes!!!!"); return 0; } string GetProgramDir() { char FullPath[MAX_PATH]; // 声明路径 string strPath = ""; GetModuleFileNameA(NULL, FullPath, MAX_PATH); // 获取当前运行程序的绝对路径 strPath = (string)FullPath; // 转为string型 int pos = static_cast<int>(strPath.find_last_of('\\', strPath.length())); return strPath.substr(0, pos); // 返回当前文件夹,不带文件名 } string GetCurrentTimeA(tm in) { tm *ct = ∈ int year, month, day, hour, minute, second;// 年月日时分秒。 year = ct->tm_year + 1900; // 年份基础从1900开始的,所以要加上 month = ct->tm_mon + 1; // 月份是0-11,对应1-12月 day = ct->tm_mday; hour = ct->tm_hour; minute = ct->tm_min; second = ct->tm_sec; char temp[100]; // 创建字符数组。 sprintf(temp, "%04d-%02d-%02d %02d:%02d:%02d: ", year, month, day, hour, minute, second);// 时间信息合并。 string out(temp); // 转化为string型 return move(out); // 用move(string)速度快很多。 } int WriteLog(string msg) { struct tm *local; time_t t; t = time(NULL); local = localtime(&t); string dtime = GetCurrentTimeA(*local); ofstream outfile; outfile.open(GetProgramDir() + "\\" + "log.txt", ios::app); //文件的物理地址,文件的打开方式, 如果没有会自动创建 if (outfile.is_open()) { outfile << dtime << msg << "\n"; outfile.close(); return 0; } else { return 1; } }
测试效果
图3 日志文件
图4 日志内容
我写的代码都力求简单好理解,方便大家自由发挥,不然一坨代码扔上去属实可能看不太懂。。。
如果这个功能有帮助到你,给点个赞吧嘿嘿~