简体   繁体   English

在C ++中获取调用函数的名称,行号和文件名

[英]Get name of calling function, line number and file name in c++

I have wrote following code to write logs in my log file. 我编写了以下代码以在日志文件中写入日志。 This code is working fine for logging messages but now i have to integrate this in multiple files i need file path of caller, caller function name and line number. 这段代码可以很好地记录消息,但是现在我必须将其集成到多个文件中,我需要调用者的文件路径,调用者函数名称和行号。

Kindly help me to achieve this . 请帮助我实现这一目标。

#include "Source.h"

bool CLogManager::fileOpenError = false;
std::string CLogManager::logFileName = "";
CLogManager* CLogManager::logManager = NULL;
FILE* CLogManager::file = NULL;

CLogManager :: CLogManager(){}
CLogManager :: ~CLogManager()
{
    if (file)
        fclose(file);
}
CLogManager* CLogManager::getInstance()
{
    if(logManager==NULL)
    {
        logManager = new CLogManager();
        logFileName = currentDateTime();
    }
    return logManager;
}
const std::string CLogManager::currentDateTime()
{
    time_t now = time(0);
    char currTime[30];
    strftime(currTime, sizeof(currTime), "Log_%Y_%m_%dT%H_%M_%S.xml", localtime(&now));
    return currTime;
}
void CLogManager::Log (char *message)
{
    file = fopen(logFileName.c_str(), "a+");
    if(file == NULL) 
    {
        if(fileOpenError == false)
        {
            std::cout << "There was an error While opening Log File."<<std::endl;
            fileOpenError = true;
        }
        return;
    }
    fputs(message, file);
    fputs("\n", file);
}

int main ()
{
    CLogManager::getInstance();
    CLogManager::Log("Sorry some error occured");
    CLogManager::Log("Please try again");
    CLogManager::Log("Wait");
    return 0;
}

When I need a fast "printf" logging, I use this marco for message logging that is branded with filename and line: 当我需要快速的“ printf”日志记录时,可以使用此marco进行消息日志记录,并带有文件名和行名:

#define _MSG(msg) do{ std::cerr << __FILE__ << "(@" << __LINE__ << "): " << msg << '\n'; } while( false )

The above macro will inject a msg into a std::cerr pipeline. 上面的宏会将msg注入到std::cerr管道中。 You can take out parts you need or modify it for your purposes. 您可以取出需要的零件,也可以根据需要对其进行修改。 It hinges on __FILE__ and __LINE__ macros, which are defined by standard: 它取决于标准定义的__FILE____LINE__宏:

__FILE__ The presumed name of the current source file (a character string literal). __FILE__当前源文件的假定名称(字符串文字)。

__LINE__ The presumed line number (within the current source file) of the current source line (an integer constant). __LINE__当前源行(一个整数常量)的假定行号(在当前源文件内)。

Function names are not so easy to get, and I don't think there is a nice way to get it. 函数名称不是那么容易获得,而且我认为没有一种很好的方法来获得它。

If you want logging through functions I would define some macro, or make function that would take int and char* for line and file respectively. 如果要通过函数登录,则可以定义一些宏,或者使函数分别将intchar*用于行和文件。 Something like log(int line, char* source_file, string message) . 诸如log(int line, char* source_file, string message)

To utilize the LogManager class that you already have written, you could do something like this: 要利用您已经编写的LogManager类,您可以执行以下操作:

void CLogManager::Log(char *message, std::string FileName = "Unset", std::string FunctionName = "Unset", int LineNumber = -1)
{
...
}

Then, anywhere you want to use your Logging function as it is right now, you would just do: 然后,在您想立即使用Logging函数的任何地方,您都可以这样做:

::Log(message);

But, if you wanted to include File/Function/Line information, you would do this: 但是,如果要包括文件/功能/行信息,则可以执行以下操作:

::Log(message, __FILE__, __FUNCTION__, __LINE__);

You can adjust the defaults from "Unset" to anything you wanted (including just ""). 您可以将默认值从“未设置”调整为所需的任何值(仅包括“”)。 I might also suggest in that function that you could have the output be different based upon whether the FileName parameter (passed to the function) is the default or not. 我可能还会建议在该函数中,根据FileName参数(传递给函数)是否为默认值,使输出有所不同。 That way your log file would look clean. 这样,您的日志文件将看起来很干净。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM