C语言中可用的标准预定义宏__FILE__显示文件的完整路径。有办法缩短这条路吗?我的意思是
/full/path/to/file.c
我看到
to/file.c
or
file.c
C语言中可用的标准预定义宏__FILE__显示文件的完整路径。有办法缩短这条路吗?我的意思是
/full/path/to/file.c
我看到
to/file.c
or
file.c
当前回答
I think this is better than using strrchr function. strfnchr will search last delemeter '/' and get filename from __FILE__ and you can use __FILE__NAME__ instead __FILE__ for get file name without full file path. strrchr solution searching filename twice per use. but this code is just 1 time search. And it works effectively even if there is no seperater '/' in __FILE__. You can use it by replacing it with \ as needed. The source code of strfnchr was improved by using the source code of strrchr below. I think it will work more effectively than strrchr. https://code.woboq.org/userspace/glibc/string/strrchr.c.html
inline const char* strfnchr(const char* s, int c) {
const char* found = s;
while (*(s++)) {
if (*s == c)
found = s;
}
if (found != s)
return found + 1;
return s;
}
#define __FILE_NAME__ strfnchr(__FILE__, '/')
其他回答
Try
#pragma push_macro("__FILE__")
#define __FILE__ "foobar.c"
在源文件中的include语句之后,然后添加
#pragma pop_macro("__FILE__")
在源文件的末尾。
I think this is better than using strrchr function. strfnchr will search last delemeter '/' and get filename from __FILE__ and you can use __FILE__NAME__ instead __FILE__ for get file name without full file path. strrchr solution searching filename twice per use. but this code is just 1 time search. And it works effectively even if there is no seperater '/' in __FILE__. You can use it by replacing it with \ as needed. The source code of strfnchr was improved by using the source code of strrchr below. I think it will work more effectively than strrchr. https://code.woboq.org/userspace/glibc/string/strrchr.c.html
inline const char* strfnchr(const char* s, int c) {
const char* found = s;
while (*(s++)) {
if (*s == c)
found = s;
}
if (found != s)
return found + 1;
return s;
}
#define __FILE_NAME__ strfnchr(__FILE__, '/')
如果您最终在本页上寻找一种方法,以从您正在交付的二进制文件中删除指向丑陋构建位置的绝对源路径,那么下面可能适合您的需要。
尽管这并没有得到作者所希望的答案,因为它假设使用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中工作
我多年来一直使用@Patrick的答案。
当完整路径包含符号链接时,它有一个小问题。
更好的解决方案。
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-builtin-macro-redefined -D'__FILE__=\"$(subst $(realpath ${CMAKE_SOURCE_DIR})/,,$(abspath $<))\"'")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-builtin-macro-redefined -D'__FILE__=\"$(subst $(realpath ${CMAKE_SOURCE_DIR})/,,$(abspath $<))\"'")
为什么要用这个?
-Wno-builtin-macro-redefined to mute the compiler warnings for redefining __FILE__ macro. For those compilers do not support this, refer to the Robust way below. Strip the project path from the file path is your real requirement. You won't like to waste the time to find out where is a header.h file, src/foo/header.h or src/bar/header.h. We should strip the __FILE__ macro in cmake config file. This macro is used in most exists codes. Simply redefine it can set you free. Compilers like gcc predefines this macro from the command line arguments. And the full path is written in makefiles generated by cmake. Hard code in CMAKE_*_FLAGS is required. There is some commands to add compiler options or definitions in some more recently version, like add_definitions() and add_compile_definitions(). These commands will parse the make functions like subst before apply to source files. That is not we want.
重新定义- wno -内置宏的健壮方法。
include(CheckCCompilerFlag)
check_c_compiler_flag(-Wno-builtin-macro-redefined SUPPORT_C_WNO_BUILTIN_MACRO_REDEFINED)
if (SUPPORT_C_WNO_BUILTIN_MACRO_REDEFINED)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-builtin-macro-redefined")
endif (SUPPORT_C_WNO_BUILTIN_MACRO_REDEFINED)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wno-builtin-macro-redefined SUPPORT_CXX_WNO_BUILTIN_MACRO_REDEFINED)
if (SUPPORT_CXX_WNO_BUILTIN_MACRO_REDEFINED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-builtin-macro-redefined")
endif (SUPPORT_CXX_WNO_BUILTIN_MACRO_REDEFINED)
记住从集合(*_FLAGS…-D__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)文件中使用,不能从头文件中使用。