log记录函数

开发中需要对软件运行中的一些数据及状态进行log记录,这里简单写下。

一、最简单的模式

#include 
#include 

int main()
{
    FILE* fp;
    fp = fopen("log.txt", "a");
    fprintf(fp, "hello world!\n");
    fclose(fp);
    
    return 0;
}

二、把核心程序提取出来

main.cpp

#include "log.h"

int main()
{
    LogSave("hello,world!\n");

    return 0;
}

log.cpp

#include 
#include 
#include "log.h"

FILE* fp;
std::string LogFileName = "log.txt";

void LogSave(const char* format)
{
    fp = fopen(LogFileName.c_str(), "a");
    if(fp != NULL)
    {
        fprintf(fp, format);
    }
    fclose(fp);
}

log.h

#ifndef LOG_H
#define LOG_H

void LogSave(const char* format);

#endif

把log程序分离出来,可以在需要的时候直接通过LogSave函数直接记录到log.txt中。

三、记录含参数的数据
上一个版本中,我们只能记录字符串,如果我们需要加参数,可以通过va_list, va_start, va_end实现。

main.cpp

#include "log.h"

int main()
{
    for(int i = 0; i < 10; i++)
    {
        LogSave("%d, hello,world!\n", i);
    }
    

    return 0;
}

log.cpp

#include 
#include 
#include 
#include "log.h"

FILE* fp;
std::string LogFileName = "log.txt";

void LogSave(const char* format, ...)
{
    va_list arg;
    va_start(arg, format);
    fp = fopen(LogFileName.c_str(), "a");
    if(fp != NULL)
    {
        vfprintf(fp, format, arg);
    }
    fclose(fp);
    va_end(arg);
}

log.h

#ifndef LOG_H
#define LOG_H

void LogSave(const char* format, ...);

#endif

这里就可以记录带参数的log了,需要注意的是将fprintf改成了vfprintf了,两者的不同在于vfprintf用于参数可变列表。

四、记录函数加锁
对于多线程来讲,如果两者同时访问了LogSave函数,可能会出现数据记录出错。这里就需要对其加锁了。通过mutex功能。mutex是c++ 11才发布的。g++编译的时候,需要加上-std=c++11
log.cpp

#include 
#include 
#include 
#include 
#include "log.h"

FILE* fp;
std::string LogFileName = "log.txt";
std::mutex Log_Mutex;

void LogSave(const char* format, ...)
{
    va_list arg;
    va_start(arg, format);

    fp = fopen(LogFileName.c_str(), "a");
    if(Log_Mutex.try_lock())
    {
        if(fp != NULL)
        {
            vfprintf(fp, format, arg);
        }
        fclose(fp);

        Log_Mutex.unlock();
    }
   
    va_end(arg);
}

当然,还可以更加丰富log函数,不过这里应该已经够用了。

你可能感兴趣的:(log函数,C++)