我有一个名为“err”的流,它位于命名空间Errors中。这就是开发人员如何以用户友好的方式报告错误。因此,当出现问题时,开发人员将编写错误消息:
Errors::err << "Oh no. That was a bad thing.";
是否可以使用预处理器将[__FILE__:__LINE__]
附加到错误消息中而不更改当前的错误报告样式?即现在上面的命令(在预处理魔术之后)将其输出到错误文件:
哦不。那是件坏事。 [file.cc:20]
我自己试过这个,但 C 预处理器似乎不喜欢命名空间,我觉得我不能在代码中的任何地方替换“错误” - 这将是一个如果开发人员决定使用using Errors::err
或using namespace Errors
,则更大的问题。
在我想要实现的范围内,C-Preprocessor是否与编码风格根本不兼容?如果有的话还有其他任何方法(可能是基于Makefile的吗?)来做我想做的事情吗?
答案 0 :(得分:5)
对于您目前的风格,这是不可能的。在运行时调用的例程不知道谁调用它们。但是,你可以obtain the backtrace using platform-specific functions写下来。
如果您可以替换所有错误报告代码,例如。与
REPORT_ERROR( "Oh no. That was a bad thing." );
这很容易。你只需#define
宏
#define REPORT_ERROR(x) Errors::err << x << "[" << __FILE__ << ":" << __LINE__ << "]" << endl;
答案 1 :(得分:4)
在这里,我认为这有效。你应该注意到这样做可能是一个坏主意,因为这段代码充其量只是时髦,完全错误或最坏无效。我没有真正测试或检查过这个,但我知道它在我的系统上编译并运行(Windows 7 / MSVC10)。如果我在生产代码中看到类似的东西,我可能会认为这是一个黑客攻击,否则必须说服。
享受。
#include <cstdlib>
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
namespace Errors
{
class errstream
{
public:
errstream(const std::string& filename, int lineno) : file_(filename), line_(lineno) {};
std::string dump() const;
errstream& operator<<(const std::string& msg)
{
cout << msg << "\t[" << file_ << ":" << line_ << "]";
return * this;
}
private:
std::string file_;
int line_;
};
};
#define err errstream(__FILE__, __LINE__)
int main()
{
Errors::err << "Oh no. That was a bad thing.";
}
输出是(对我来说):
哦不。那是件坏事。 [main.cpp中:30]
在下面的评论中,提出了新的要求。 OP希望能够做到这样的事情:
Errors::err << "File Not Found '" << file << "' What A Bummer. :(";
...并输出为:
找不到档案! 'foo.txt'多么糟糕。 :([file:nnn]
我的原始代码不会产生此输出,因为它只能为该位置添加一个附加标记来处理多个流插入。输出反而成了一大堆:
找不到档案! '[main.cpp:61] foo.txt [main.cpp:61]'真是太棒了 无赖。 :( [main.cpp:61]
当调用析构函数时,errstream
将其内容转储到cout
,而不是在调用流插入运算符时,可以容纳这种情况。反过来,流插入操作员会收集将在位置字符串之前转储到cout的令牌。新代码:
#include <cstdlib>
#include <sstream>
#include <string>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
namespace Errors
{
class errstream
{
public:
errstream(const std::string& filename, int lineno) : file_(filename), line_(lineno) {};
~errstream()
{
std::copy(tokens_.begin(), tokens_.end(), ostream_iterator<string>(cout));
cout << "\t[" << file_ << ":" << line_ << "]\n";
}
errstream& operator<<(const std::string& msg)
{
tokens_.push_back(msg);
return *this;
}
private:
typedef std::vector<std::string> Tokens;
Tokens tokens_;
std::string file_;
int line_;
};
};
#define err errstream(__FILE__, __LINE__)
int main()
{
Errors::err << "Oh no. That was a bad thing.";
string file = "foo.txt";
Errors::err << "File not found! '" << file << "' What a bummer. :(";
}
输出现在是:
哦不。那是件坏事。 [main.cpp:38]
找不到档案! 'foo.txt'多么糟糕。 :( [main.cpp:41]