log打印函数(基于C/C++)

发布于:2022-12-28 ⋅ 阅读:(580) ⋅ 点赞:(0)

实验题目:使用C/C++编写log打印函数
实验要求:1.将log打印函数定义在 plfapi.h 文件中
                  2.使用枚举定义trace、debug、error等lever的打印级别,并可在main.cpp里实现切换
                  3.函数的进来和出去使用trace等级打印;函数返回值、函数入参、switch、if的条件、子函数内参数使用debug等级打印;错误使用error等级打印;主函数内的运行结果使用msg等级打印。     

实验环境与工具:1.Linux、ubuntu20、gcc7.4.0、secureCRT4.0、notepad++

                             2.vs2019 x86

说明:1.本实验共编写两类打印函数。

           2.一类是基于printf的log打印函数,该函数使用起来比较麻烦,需要%d、%c、%s、\n等参数,但清晰明了,知道需要打印的参数是什么类型的,能够加深新手对C语言基础的理解。

          3.一类是基于C++类的log打印函数,该函数使用起来简单,无需第一类的操作。

          4.这两类log打印函数可使用在linux环境下,亦可使用与vs2019(低版本兼容)中。

          5.码字不易,希望各位看官点个赞,十分感谢!!!!!

目录

一、基于printf的log打印函数

        1.plfapi.h 程序:

        2. main.cpp程序

        3.实验结果

二、基于C++类的log打印函数

1.logbase.h 程序

2. main.cpp程序

3.实验结果



一、基于printf的log打印函数

1.plfapi.h 程序:

/*!
*************************************************************************************************
* @file  plfapi.h
* @brief
* @author
* date
*************************************************************************************************
*/

#ifndef _PLFAPI_DEBUG_H_
#define _PLFAPI_DEBUG_H_
#include <stdio.h>
#include <string.h>
//#include "unistd.h"
#include <io.h>
#include <process.h>

class SourceFile_PLFAPI
{
public:
    template <int N>
    inline explicit SourceFile_PLFAPI(const char (&arr)[N])
        :data_(arr)
        , size_(N - 1)
    {
        const char* slash = strrchr(data_, '/');
        if (slash)
        {
            data_ = slash + 1;
            size_ = static_cast<int>(data_ - arr);
        }
    }

    explicit SourceFile_PLFAPI(const char* filename)
        :data_(filename)
    {
        const char* slash = strrchr(filename, '/');
        if (slash)
        {
            data_ = slash + 1;
        }
        size_ = static_cast<int>(strlen(data_));
    }

    const char* data_;
    int size_;
};

enum enPlfapiMessage
{
    g_plfapi_none,
    g_plfapi_err,
    g_plfapi_msg,
    g_plfapi_dbg,
    g_plfapi_trace,
    g_plfapi_all,
};

extern enPlfapiMessage g_Plfapi_layer;

//notice: FILE LINE func VA_ARGS has four '_'
#define PLFAPI_TRACE(...)                                                                     \
if (g_plfapi_trace <= g_Plfapi_layer)                                                         \
{                                                                                             \
    printf("[PLFAPI_TRACE] %s#%d@%s", SourceFile_PLFAPI(__FILE__).data_, __LINE__, __func__); \
    printf(__VA_ARGS__);                                                                      \
}                                                                                             \

#define PLFAPI_DBG(...)                                                                     \
if (g_plfapi_dbg <= g_Plfapi_layer)                                                         \
{                                                                                           \
    printf("[PLFAPI_DBG] %s#%d@%s", SourceFile_PLFAPI(__FILE__).data_, __LINE__, __func__); \
    printf(__VA_ARGS__);                                                                    \
}                                                                                           \

#define PLFAPI_MSG(...)                                                                      \
if (g_plfapi_msg <= g_Plfapi_layer)                                                          \
{                                                                                            \
    printf("[PLFAPI_MSGE] %s#%d@%s", SourceFile_PLFAPI(__FILE__).data_, __LINE__, __func__); \
    printf(__VA_ARGS__);                                                                     \
}                                                                                            \

#define PLFAPI_ERR(...)                                                                     \
if (g_plfapi_err <= g_Plfapi_layer)                                                         \
{                                                                                           \
    printf("[PLFAPI_ERR] %s#%d@%s", SourceFile_PLFAPI(__FILE__).data_, __LINE__, __func__); \
    printf(__VA_ARGS__);                                                                    \
}          

2. main.cpp程序

/*!
*************************************************************************************************
* @file  main.cpp
* @brief
* @author
* date
*************************************************************************************************
*/

#include <stdlib.h>
#include <string>
#include <fstream>
#include <iostream>

#include "plfapi_debug.h"

/* by changing ERR parameters to DBG, ALL, MSG, and trace, 
   different printing levels can be switched*/

enPlfapiMessage g_Plfapi_layer = g_plfapi_err;
//enPlfapiMessage g_Plfapi_layer = g_plfapi_all;
//enPlfapiMessage g_Plfapi_layer = g_plfapi_msg;

/*!
* @brief 
*/
int main()
{
    PLFAPI_TRACE("in\n");
    
    int iRet = -1;
    char s[3] = "ab";
    char *pKeyWord = NULL;
    pKeyWord = (char *)malloc(sizeof(char) * 3);
    if (pKeyWord == NULL)
    {
        PLFAPI_ERR("pKeyWord is null\n");
        PLFAPI_DBG("ret: %d\n", iRet);
        PLFAPI_TRACE("out\n");
        return iRet;
    }
    memset(pKeyWord, 0, (sizeof(char) * 2));
    strncpy(pKeyWord, s, 3);

    PLFAPI_MSG("pKeyWord :%s\n", pKeyWord);

    if (pKeyWord != NULL)
    {
        free(pKeyWord);
        pKeyWord = NULL;
    }

    PLFAPI_DBG("ret: %d\n", iRet);
    PLFAPI_TRACE("out\n");
    return iRet;
}

3.实验结果

二、基于C++类的log打印函数

1.logbase.h 程序

/*!
*************************************************************************************************
* @file  logbase.h
* @brief
* @author
* date
*************************************************************************************************
*/

#ifndef _LOGBASE_H
#define _LOGBASE_H

#include <cstddef>
#include <vector>
#include <string>
#include <string.h>

#define MGR_UNUSED(Argument) static_cast<void>(Argument);
#define MGR_DISABLE_COPY(Typename) \
    Typename(const Typename&); \
    Typename& operator = (const Typename&); \

#include <cstdio>
#define MGR_DEBUG(...) printf("[MGR]: "__VA_ARGS__);

#include <cassert>
#define MGR_ASSERT(expression) assert(expression);

#define MGR_ENABLE_LOG

enum enAPMessageLayer
{
    EN_LAYER_NONE = 0,
    EN_LAYER_ERR = 1,
    EN_LAYER_INFO = 2,
    EN_LAYER_DBG = 3,
    EN_LAYER_TRACE = 4,
    EN_LAYER_ALL = 5,
};

class SourceFile
{
public:
    template <int N>
    inline explicit SourceFile(const char(&arr)[N])
        :data_(arr)
        , size_(N - 1)
    {
        const char* slash = strrchr(data_, '/');
        if (slash)
        {
            data_ = slash + 1;
            size_ = static_cast<int>(data_ - arr);
        }
    }

    explicit SourceFile(const char* filename)
        :data_(filename)
    {
        const char* slash = strrchr(filename, '/');
        if (slash)
        {
            data_ = slash + 1;
        }
        size_ = static_cast<int>(strlen(data_));
    }

    const char* data_;
    int size_;
};

#ifdef MGR_ENABLE_LOG
#define MGR_LOGD \
        LogHelper::LogD(MGR_LOG_TAG)
#define MGR_LOGI \
        LogHelper::LogI(MGR_LOG_TAG)
#define MGR_LOGE \
        LogHelper::LogE(MGR_LOG_TAG) << SourceFile(__FILE__).data_ << "#" << __LINE__ << "@" << __FUNCTION__ << ": "
#define MGR_LOGT \
        LogHelper::LogT(MGR_LOG_TAG) << SourceFile(__FILE__).data_ << "#" << __LINE__ << "@" << __FUNCTION__ << ": "
#else
#define MGR_LOGD
#define MGR_LOGI
#define MGR_LOGE
#define MGR_LOGT
#endif

/*!
*.@brief for debug code
*
*/
extern enAPMessageLayer g_APMessageLayer;
class LogHelper
{
private:
    enAPMessageLayer m_level;
public:
    LogHelper(const char* type, const char* tag)
    {
        printf("<< MGR >> - @%s(%s): ", tag, type);

        switch (*type)
        {
        case 'D':
            m_level = EN_LAYER_DBG;
            break;
        case 'E':
            m_level = EN_LAYER_ERR;
            break;
        case 'I':
            m_level = EN_LAYER_INFO;
            break;
        case 'T':
            m_level = EN_LAYER_TRACE;
            break;
        default:
            m_level = EN_LAYER_NONE;
            break;
        }
    }

    explicit LogHelper(const char* type)
    {
        switch (*type)
        {
        case 'D':
            m_level = EN_LAYER_DBG;
            break;
        case 'E':
            m_level = EN_LAYER_ERR;
            break;
        case 'I':
            m_level = EN_LAYER_INFO;
            break;
        case 'T':
            m_level = EN_LAYER_TRACE;
            break;
        default:
            m_level = EN_LAYER_NONE;
            break;
        }
    }

    ~LogHelper()
    {
        if (g_APMessageLayer != EN_LAYER_NONE)
        {
            if (m_level <= g_APMessageLayer)
            {
                printf("\n");
            }
        }
    }

    static void setLogLayer(enAPMessageLayer layer)
    {
        g_APMessageLayer = layer;
    }

    static LogHelper LogD(const char* tag)
    {
        if ((g_APMessageLayer == EN_LAYER_DBG) || (g_APMessageLayer == EN_LAYER_ALL))
        {
            return LogHelper("D", tag);
        }
        else
        {
            return LogHelper("D");
        }
    }

    static LogHelper LogE(const char* tag)
    {
        if ((g_APMessageLayer == EN_LAYER_ERR) || (g_APMessageLayer == EN_LAYER_ALL))
        {
            return LogHelper("E", tag);
        }
        else
        {
            return LogHelper("E");
        }
    }

    static LogHelper LogI(const char* tag)
    {
        if ((g_APMessageLayer == EN_LAYER_INFO) || (g_APMessageLayer == EN_LAYER_ALL))
        {
            return LogHelper("I", tag);
        }
        else
        {
            return LogHelper("I");
        }
    }

    static LogHelper LogT(const char* tag)
    {
        if ((g_APMessageLayer == EN_LAYER_TRACE) || (g_APMessageLayer == EN_LAYER_ALL))
        {
            return LogHelper("T", tag);
        }
        else
        {
            return LogHelper("T");
        }
    }

    LogHelper& operator << (const std::string& str)
    {
        if (g_APMessageLayer != EN_LAYER_NONE)
        {
            if (m_level <= g_APMessageLayer)
            {
                printf("%s", str.c_str());
            }
        }
        return *this;
    }

    LogHelper& operator << (const char* cstr)
    {
        if (g_APMessageLayer != EN_LAYER_NONE)
        {
            if (cstr)
            {
                printf("%s", cstr);
            }
        }
        return *this;
    }

    LogHelper& operator << (int value)
    {
        if (g_APMessageLayer != EN_LAYER_NONE)
        {
            printf("%d", value);
        }
        return *this;
    }
};
#endif

2. main.cpp程序

/*!
*************************************************************************************************
* @file  logbase.h
* @brief
* @author
* date
*************************************************************************************************
*/
#include <fstream>
#include <iostream>
#include <string.h>
#include <stdlib.h>

#include "logbase.h"
enAPMessageLayer g_APMessageLayer = EN_LAYER_ALL;
//enAPMessageLayer g_APMessageLayer = EN_LAYER_ERR;
//enAPMessageLayer g_APMessageLayer = EN_LAYER_INFO;

#define MGR_LOG_TAG "Main"
int main()
{
    MGR_LOGT << "in";
    int iRet = -1;
    char s[3] = "ab";
    char* pKeyWord = NULL;
    pKeyWord = (char*)malloc(sizeof(char) * 3);
    if (NULL == pKeyWord)
    {
        MGR_LOGE << "pKeyWord is null";
        MGR_LOGD << "ret: " << iRet;
        MGR_LOGT << "out";
        return iRet;
    }
    memset(pKeyWord, 0, (sizeof(char) * 2));
    memcpy(pKeyWord, s, 3);

    MGR_LOGI << "s: " << s;
    MGR_LOGI << "pKeyWord: " << pKeyWord;

    if (pKeyWord != NULL)
    {
        free(pKeyWord);
        pKeyWord = NULL;
    }

    MGR_LOGD << "ret: " << iRet;
    MGR_LOGT << "out";
    return iRet;
}

3.实验结果