C语言中可用的标准预定义宏__FILE__显示文件的完整路径。有办法缩短这条路吗?我的意思是

/full/path/to/file.c

我看到

to/file.c

or

file.c

当前回答

Try

#pragma push_macro("__FILE__")
#define __FILE__ "foobar.c"

在源文件中的include语句之后,然后添加

#pragma pop_macro("__FILE__")

在源文件的末尾。

其他回答

下面是一个解决方案,适用于没有字符串库的环境(Linux内核,嵌入式系统等):

#define FILENAME ({ \
    const char* filename_start = __FILE__; \
    const char* filename = filename_start; \
    while(*filename != '\0') \
        filename++; \
    while((filename != filename_start) && (*(filename - 1) != '/')) \
        filename--; \
    filename; })

现在只需使用FILENAME而不是__FILENAME__。是的,它仍然是一个运行时的东西,但它是有效的。

只是希望改进一下FILE宏:

#定义文件(strrchr(__FILE__, '/') ?strrchr __FILE __, '/') + 1: strrchr __FILE __, '\\') ?strrchr(__FILE__, '\\') + 1: __FILE__)

这捕获/和\,像Czarek Tomczak要求的,这在我的混合环境中工作得很好。

我做了一个宏__FILENAME__,以避免每次都切割完整路径。问题是将结果文件名保存在cppp -local变量中。

这可以通过在.h文件中定义一个静态全局变量来轻松实现。 这个定义在每个.cpp文件中给出了独立的变量。 为了成为一个多线程证明,值得让变量也是线程本地(TLS)。

一个变量存储文件名(压缩后)。另一个保存了__FILE__给出的非剪切值。h文件:

static __declspec( thread ) const char* fileAndThreadLocal_strFilePath = NULL;
static __declspec( thread ) const char* fileAndThreadLocal_strFileName = NULL;

宏本身使用所有逻辑调用方法:

#define __FILENAME__ \
    GetSourceFileName(__FILE__, fileAndThreadLocal_strFilePath, fileAndThreadLocal_strFileName)

函数是这样实现的:

const char* GetSourceFileName(const char* strFilePath, 
                              const char*& rstrFilePathHolder, 
                              const char*& rstrFileNameHolder)
{
    if(strFilePath != rstrFilePathHolder)
    {
        // 
        // This if works in 2 cases: 
        // - when first time called in the cpp (ordinary case) or
        // - when the macro __FILENAME__ is used in both h and cpp files 
        //   and so the method is consequentially called 
        //     once with strFilePath == "UserPath/HeaderFileThatUsesMyMACRO.h" and 
        //     once with strFilePath == "UserPath/CPPFileThatUsesMyMACRO.cpp"
        //
        rstrFileNameHolder = removePath(strFilePath);
        rstrFilePathHolder = strFilePath;
    }
    return rstrFileNameHolder;
}

removePath()可以以不同的方式实现,但最简单快捷的方法似乎是使用strrchr:

const char* removePath(const char* path)
{
    const char* pDelimeter = strrchr (path, '\\');
    if (pDelimeter)
        path = pDelimeter+1;

    pDelimeter = strrchr (path, '/');
    if (pDelimeter)
        path = pDelimeter+1;

    return path;
}

对于Visual Studio,您可以使用/d1trimfile选项。

你可能想把它设置为/d1trimfile:"$(SolutionDir)\":

注意:“”前面加了\的解释:

要转义第一个($(SolutionDir)以反斜杠结束),否则将转义引号。你需要等量的反斜杠 在引用之前。

Try

#pragma push_macro("__FILE__")
#define __FILE__ "foobar.c"

在源文件中的include语句之后,然后添加

#pragma pop_macro("__FILE__")

在源文件的末尾。