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

/full/path/to/file.c

我看到

to/file.c

or

file.c

当前回答

如果您最终在本页上寻找一种方法,以从您正在交付的二进制文件中删除指向丑陋构建位置的绝对源路径,那么下面可能适合您的需要。

尽管这并没有得到作者所希望的答案,因为它假设使用CMake,但它已经非常接近了。很遗憾之前没有人提到这一点,因为这可以节省我很多时间。

OPTION(CMAKE_USE_RELATIVE_PATHS "If true, cmake will use relative paths" ON)

将上述变量设置为ON将生成如下格式的构建命令:

cd /ugly/absolute/path/to/project/build/src && 
    gcc <.. other flags ..> -c ../../src/path/to/source.c

因此,__FILE__宏将解析为../../src/path/to/source.c

CMake文档

但是要注意文档页上的警告:

使用相对路径(可能不起作用!)

它不能保证在所有情况下都能工作,但在我的CMake 3.13 + gcc 4.5中工作

其他回答

Try

#include <string.h>

#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

对于Windows,使用“\\”而不是“/”。

对@red1ynx提议的轻微变化将创建以下宏:

#define SET_THIS_FILE_NAME() \
    static const char* const THIS_FILE_NAME = \
        strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__;

在每一个。c(pp)文件中添加:

SET_THIS_FILE_NAME();

然后你可以引用THIS_FILE_NAME而不是__FILE__:

printf("%s\n", THIS_FILE_NAME);

这意味着每个.c(pp)文件执行一次构造,而不是每次引用宏时都执行。

它仅限于从.c(pp)文件中使用,不能从头文件中使用。

c++ 11 msvc2015u3、gcc5.4 clang3.8.0 模板<typename T, size_t S> (const T (& str)[S], size_t i = S - 1) { 返回(str[i] == '/' || str[i] == '\\') ?I + 1:(I > 0 ?Get_file_name_offset (str, I - 1): 0); } template <typename T> (T (& str)[1]) { 返回0; }

'

    int main()
    {
         printf("%s\n", &__FILE__[get_file_name_offset(__FILE__)]);
    }

代码在以下情况下产生编译时偏移量:

gcc:至少gcc6.1 + -O1 Msvc:将结果放入constexpr变量: constexpr auto file = &__FILE__[get_file_name_offset(__FILE__)]; printf (" % s \ n ",文件); Clang:坚持不编译时计算

有一个技巧可以强制所有3个编译器进行编译时间计算,即使在调试配置中禁用优化:

    namespace utility {

        template <typename T, T v>
        struct const_expr_value
        {
            static constexpr const T value = v;
        };

    }

    #define UTILITY_CONST_EXPR_VALUE(exp) ::utility::const_expr_value<decltype(exp), exp>::value

    int main()
    {
         printf("%s\n", &__FILE__[UTILITY_CONST_EXPR_VALUE(get_file_name_offset(__FILE__))]);
    }

https://godbolt.org/z/u6s8j3

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

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

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

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

使用basename()函数,或者,如果是在Windows上,使用_splitpath()。

#include <libgen.h>

#define PRINTFILE() { char buf[] = __FILE__; printf("Filename:  %s\n", basename(buf)); }

还可以在shell中尝试man 3 basename。