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

/full/path/to/file.c

我看到

to/file.c

or

file.c

当前回答

纯粹的编译时解决方案。它基于这样一个事实:字符串字面量的sizeof()返回其长度+1。

#define STRIPPATH(s)\
    (sizeof(s) > 2 && (s)[sizeof(s)-2] == '/' ? (s) + sizeof(s) - 1 : \
    sizeof(s) > 3 && (s)[sizeof(s)-3] == '/' ? (s) + sizeof(s) - 2 : \
    sizeof(s) > 4 && (s)[sizeof(s)-4] == '/' ? (s) + sizeof(s) - 3 : \
    sizeof(s) > 5 && (s)[sizeof(s)-5] == '/' ? (s) + sizeof(s) - 4 : \
    sizeof(s) > 6 && (s)[sizeof(s)-6] == '/' ? (s) + sizeof(s) - 5 : \
    sizeof(s) > 7 && (s)[sizeof(s)-7] == '/' ? (s) + sizeof(s) - 6 : \
    sizeof(s) > 8 && (s)[sizeof(s)-8] == '/' ? (s) + sizeof(s) - 7 : \
    sizeof(s) > 9 && (s)[sizeof(s)-9] == '/' ? (s) + sizeof(s) - 8 : \
    sizeof(s) > 10 && (s)[sizeof(s)-10] == '/' ? (s) + sizeof(s) - 9 : \
    sizeof(s) > 11 && (s)[sizeof(s)-11] == '/' ? (s) + sizeof(s) - 10 : (s))

#define __JUSTFILE__ STRIPPATH(__FILE__)

请随意将条件操作符级联扩展到项目中最大的合理文件名。路径长度并不重要,只要检查距离字符串的末尾足够远。

我将看看我是否可以得到一个类似的宏,没有硬编码的长度与宏递归…

其他回答

如果您正在使用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__。

编译时没有办法做到这一点。显然,您可以在运行时使用C运行时实现它,正如其他一些答案所演示的那样,但是在编译时,当预处理器启动时,您就不走运了。

red1ynx的答案经过调整,甚至更加“臃肿”:

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

如果我们发现反斜杠,我们就分反斜杠。否则,拆分为正斜杠。很简单。

几乎任何替代方案都会更简洁(在我看来,c++ constexpr确实是这里的黄金标准)。然而,如果你正在使用一些__BASE_FILE__不可用的编译器,这可能是有帮助的。

Try

#include <string.h>

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

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

只是希望改进一下FILE宏:

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

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