简体   繁体   English

如何在字符串中使用编译时常量__LINE__?

[英]How can I use the compile time constant __LINE__ in a string?

I can use __LINE__ as a method parameter just fine, but I would like an easy way to use it in a function that uses strings. 我可以使用__LINE__作为方法参数,但我希望在使用字符串的函数中使用它很简单。

For instance say I have this: 比如说我有这个:

11    string myTest()
12    {
13     if(!testCondition)
14       return logError("testcondition failed");
15    }

And I want the result of the function to be: 我希望函数的结果是:

"myTest line 14: testcondition failed" “myTest第14行:testcondition失败”

How can I write logError? 我怎么写logError? Does it have to be some monstrosity of a macro? 它是否必须是一个宏观的怪物?

There's no reason to do any run-time work for this: 没有理由为此做任何运行时工作:

#include <iostream>

// two macros ensures any macro passed will
// be expanded before being stringified
#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)

// test
void print(const char* pStr)
{
    std::cout << pStr << std::endl;
}

int main(void)
{
    // adjacent strings are concatenated
    print("This is on line #" STRINGIZE(__LINE__) ".");
}

Or: 要么:

#define STOP_HAMMER_TIME(x) #x
#define STRINGIFICATE(x) STOP_HAMMER_TIME(x)

If you're a cool person like James. 如果你像詹姆斯一样酷。

Why do you even need it as a string? 为什么你甚至需要它作为一个字符串? What's wrong with an integer? 整数有什么问题? Here are two ways you could write logError() : 您可以通过以下两种方式编写logError()

#define logError(str) fprintf(stderr, "%s line %d: %s\n", __FILE__, __LINE__, str)

// Or, forward to a more powerful function
#define logError(str) logError2(__FILE__, __LINE__, str)
void logError2(const char *file, int line, const char *str);

If you really need the line as a string, you can use the stringizing operator # , but because of the way macros work, you'll need to wrap it in two macros: 如果你真的需要将该行作为字符串,你可以使用字符串化运算符# ,但由于宏的工作方式,你需要将它包装在两个宏中:

#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#define LINE_STRING STRINGIZE(__LINE__)

And now LINE_STRING is a macro that will expand to a string containing the current line number wherever it is expanded. 现在LINE_STRING是一个宏,它将扩展为包含当前行号的字符串,无论它在哪里展开。 If you only had one level of macros (ie if you had #define STRINGIZE(x) #x ), then you would get the literal string "__LINE__" every time you expanded it, which is not what you want. 如果你只有一个级别的宏(即如果你有#define STRINGIZE(x) #x ),那么你每次扩展它时都会得到文字字符串"__LINE__" ,这不是你想要的。

His goal is to create a macro (named logError ) that will automatically include the symbols necessary and do the string concatenation within the preprocessor, only using string literals. 他的目标是创建一个宏(名为logError ),它将自动包含必要的符号,并在预处理器中执行字符串连接,仅使用字符串文字。

So, combining the basically-correct answers answers thus far, let's write the macro: 所以,到目前为止,结合基本正确的答案答案,让我们写宏:

#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
#define logError(msg) (__FILE__ " line " STRINGIZE(__LINE__) ": " msg)

You can then use this macro anywhere to create a generic error message code in string literal format at compile time. 然后,您可以在任何位置使用此宏来在编译时以字符串文字格式创建一般错误消息代码。

Note: You can also use __FUNCTION__ (or an equivalent, it varies by compiler) instead of __FILE__ , if you prefer, to keep track of the function name instead of the file name. 注意:如果您愿意,还可以使用__FUNCTION__ (或等效的,因编译器而异,而不是__FILE__ )来跟踪函数名称而不是文件名。

The usual options for formatting a number into a string apply: Boost lexical_cast, ostringstream, sprintf or snprintf, etc. 将数字格式化为字符串的常用选项适用:Boost lexical_cast,ostringstream,sprintf或snprintf等。

Here is one of my favorite links on the topic: http://www.gotw.ca/publications/mill19.htm 以下是我最喜欢的主题之一: http//www.gotw.ca/publications/mill19.htm

Yes, it's ugly. 是的,这很难看。 You need a combination of macros. 您需要组合宏。 Converting an integer to a string is a two-step process - here's Boost's implementation: 将整数转换为字符串是一个两步的过程 - 这是Boost的实现:

#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X)
#define BOOST_DO_STRINGIZE(X) #X

Now you can generate a string: 现在您可以生成一个字符串:

logError(__FILE__ BOOST_STRINGIZE(__LINE__) "testcondition failed");   
std::string logError(const char* file, int line, const char* msg)
{
   std::ostringstream os;
   os << file << ' ' << line << ':' << msg;
   return os.str();
}

Usage: 用法:

return logError(__FILE__, __LINE__, "my error message");

You could then make a macro for this if you were so inclined: 如果您愿意,可以为此制作一个宏:

#define LOG_ERROR(x) logError(__FILE__, __LINE__, (x))

And then the usage would be: 然后用法是:

return LOG_ERROR("my error message");
sprintf(newStringBuffer, "myTest line %d: testcondition failed\n", __LINE__);

should do it c style. 应该做的风格。 I know that there are ways and ways of doing this with the C++ string libraries. 我知道有很多方法和方法可以使用C ++字符串库。

You could also use strcat() or strncat or any other number of C libs to do this. 您也可以使用strcat()或strncat或任何其他数量的C lib来执行此操作。

cout <<"String" + __LINE__ + " another string" 

will work as well. 也会奏效。

Try this? 试试这个?

string myTest(const int lineno)
{
  if(!testCondition)
    return logError ("testcondition failed", lineno);
}

void logError (string msg, const int lineno)
{
  clog << "line " << lineno << ": " << msg << endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在编译时从 __FILE__ 获取文件名并与 __LINE__ 连接 - How to get filename from __FILE__ and concat with __LINE__ at compile time 如何在本机nodejs插件中使用环境变量作为编译时常量? - How can I use environment variable as compile-time constant in native nodejs addon? 我可以在 C++ 的内联 function 中使用 __LINE__ 或 __FILE__ 吗? - Can I use __LINE__ or __FILE__ in inline function in C++? 如何使用编译时间常数原语的类型 - how to use the type of compile time constant primitive 如何在c ++的构造函数中使用__FILE__和__LINE__作为默认参数? - How do I use __FILE__ and __LINE__ as default parameters in a constructor in c++? 如何用支持__LINE__和__FILE__的内联函数替换我的c ++异常宏? - How can I replace my c++ exception macro with an inline function with __LINE__ and __FILE__ support? 如何让预处理器为__LINE__关键字生成一个字符串? - How to make preprocessor generate a string for __LINE__ keyword? 如何创建带有前置长度字节的编译时常量字符串? - How to create compile-time constant string with prepended length byte? 如何在#cc文件中使#include-file的内容成为编译时常量? - How can I make the contents of an #include-file a compile-time constant in a cpp-file? 如何使这个涉及浮点函数的表达式成为编译时常量? - How can I make this expression involving floating-point functions a compile-time constant?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM