作者:Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
场景需求
开发软件或者进行其他编程工作时,软件可能会长时间运行,但是!一旦突然崩溃就让人一脸懵逼,此时,日志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 日志内容
我写的代码都力求简单好理解,方便大家自由发挥,不然一坨代码扔上去属实可能看不太懂。。。
如果这个功能有帮助到你,给点个赞吧嘿嘿~