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__")

在源文件的末尾。

其他回答

对@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)文件中使用,不能从头文件中使用。

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

#include <libgen.h>

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

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

如果您正在使用cmake,这里有一个提示。来自: http://public.kitware.com/pipermail/cmake/2013-January/053117.html

我在复制提示,所以都在这一页上:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst
  ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")

如果您正在使用GNU make,我认为没有理由不能将其扩展到您自己的make文件。例如,你可能有这样的一行:

CXX_FLAGS+=-D__FILENAME__='\"$(subst $(SOURCE_PREFIX)/,,$(abspath $<))\"'"

其中$(SOURCE_PREFIX)是要删除的前缀。

然后使用__FILENAME__代替__FILE__。

至少对于gcc, __FILE__的值是编译器命令行中指定的文件路径。如果你像这样编译file.c:

gcc -c /full/path/to/file.c

__FILE__将展开为“/full/path/to/file.c”。如果你这样做:

cd /full/path/to
gcc -c file.c

那么__FILE__将展开为“file.c”。

这可能是实际的,也可能不是。

C标准不要求这种行为。关于__FILE__,它只是将其扩展为“当前源文件的假定名称(字符串字面值)”。

另一种方法是使用#line指令。它覆盖当前行号,也可选择覆盖源文件名。如果你想覆盖文件名但保留行号,使用__LINE__宏。

例如,你可以把它添加到文件的顶部。c:

#line __LINE__ "file.c"

唯一的问题是它将指定的行号赋给下一行,而#line的第一个参数必须是一个数字序列,因此您不能执行类似的操作

#line (__LINE__-1) "file.c"  // This is invalid

确保#line指令中的文件名与文件的实际名称匹配作为练习。

至少对于gcc来说,这也会影响诊断消息中报告的文件名。

一个简短的,适用于Windows和*nix的答案:

#define __FILENAME__ std::max<const char*>(__FILE__,\
    std::max(strrchr(__FILE__, '\\')+1, strrchr(__FILE__, '/')+1))