C++ Cpp预处理器和文件名的basename,行号为字符串

C++ Cpp预处理器和文件名的basename,行号为字符串,c++,gcc,c-preprocessor,C++,Gcc,C Preprocessor,我想用预处理器生成一个形式为“example.cpp:34”的静态字符串,但是\uuuuuuu文件\uuuuuuuuuu宏将扩展为“lib/example/example.cpp”,而\uuuuuuuuuu LINE\uuuuuu将扩展为一个整数。我可以用预处理器构造所需的字符串吗?GCC扩展还可以 编辑这里最重要的部分是我想要一个静态C样式的字符串,所以我不能使用basename函数。我想知道预处理器中是否有某种方法可以复制该功能,可能是通过一个boost扩展?您应该能够在\uuu文件扩展为常

我想用预处理器生成一个形式为
“example.cpp:34”
的静态字符串,但是
\uuuuuuu文件\uuuuuuuuuu
宏将扩展为
“lib/example/example.cpp”
,而
\uuuuuuuuuu LINE\uuuuuu
将扩展为一个整数。我可以用预处理器构造所需的字符串吗?GCC扩展还可以


编辑这里最重要的部分是我想要一个静态C样式的字符串,所以我不能使用
basename
函数。我想知道预处理器中是否有某种方法可以复制该功能,可能是通过一个boost扩展?

您应该能够在
\uuu文件扩展为常量C字符串时使用
basename()

\uuuuuuuuuu文件 此宏以C字符串常量的形式扩展为当前输入文件的名称


您可以利用相邻字符串文字是串联的这一事实:

#define STRINGIFY(s) #s
#define FILELINE(line) __FILE__ ":" str(line)
然后像
FILELINE(\uuuuline\uuuuu)
一样使用它。我不经常这样做,因此可能有一种比必须传递
\uuu行\uu
宏更好的方法。不管怎样,它对我来说是有效的,通过以下方式进行测试:

#include <iostream>

#define str(s) #s
#define FILELINE(line) __FILE__ ":" str(line)

int main(int argc, const char* argv[])
{
  std::cout << FILELINE(__LINE__) << std::endl;
  return 0;
}

我不知道如何获取basename,但除此之外,还可以使用字符串化预处理器运算符“#”,如:


现在
M
将扩展到
“lib/example/example.cpp:34”
(假设您将其放在该行的文件中,ofc:)

那么,不仅必须使用预处理器,而且最终用户不会看到它

如果希望在某些文件中使用
BASENAME()
,请使用此头文件
BASENAME.h

// basename.h
#include <string.h>

static size_t basename_start_calc(const char* filename)
{
    const char* base = strrchr(filename, '/');
    return base ? (base - filename + 1) : 0;
}
static inline size_t basename_start(const char* filename)
{
    static size_t retval = basename_start_calc(filename);
    return retval;
}
#define STR_(t) #t
#define STR(t) STR_(t)
#define BASENAME()  ((__FILE__ ":" STR(__LINE__)) + basename_start(__FILE__))

但我不确定这是否是您想要的….

C++11可以吗?字符串必须在预处理器中使用,还是仅在编译时使用?@KennyTM不,我不能使用C++11。我希望在编译时使用它。Boost也可以。或者不要使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。很抱歉当然,所以我想问题其实在于基本名称。您之所以获得main.cpp,是因为您没有在其他目录中包含文件。我需要一个静态c字符串,因此它不能是函数的输出。@pythonicaperager函数的输出是什么意思?你想从函数中返回它吗?我的意思是我想要一个静态字符串,所以我不能使用任何函数,只能使用预处理器来构造它。@pythonic这在C预处理器中是不可能的,为什么你想要一个静态字符串?也许还有另一种方法。是的,我发现这是不可能的,这很遗憾
main.cpp:9
#define M__(x,y) x ":" #y
#define M_(x,y) M__(x, y)
#define M M_(__FILE__, __LINE__)
// basename.h
#include <string.h>

static size_t basename_start_calc(const char* filename)
{
    const char* base = strrchr(filename, '/');
    return base ? (base - filename + 1) : 0;
}
static inline size_t basename_start(const char* filename)
{
    static size_t retval = basename_start_calc(filename);
    return retval;
}
#define STR_(t) #t
#define STR(t) STR_(t)
#define BASENAME()  ((__FILE__ ":" STR(__LINE__)) + basename_start(__FILE__))
#define BASENAME()  ("somefile.cpp:" STR(__LINE__))