c++ - 如何运行 Wave 快速入门示例?
问题描述
(源自这个问题。)
我没有成功地尝试使用这个例子。
我的尝试是复制并稍微编辑链接处的代码。结果是这样的(我留下了 Boost 网站的评论,以便更容易地将我的编辑与原始版本进行比较):
#include <boost/wave.hpp>
#include <boost/wave/cpplexer/cpp_lex_iterator.hpp>
int main() {
// The following preprocesses a given input file.
// Open the file and read it into a string variable
std::string input("int main() { std::cout << \"Hello world\"; }");
// The template boost::wave::cpplexer::lex_token<> is the
// token type to be used by the Wave library.
// This token type is one of the central types throughout
// the library, because it is a template parameter to some
// of the public classes and templates and it is returned
// from the iterators.
// The template boost::wave::cpplexer::lex_iterator<> is
// the lexer iterator to use as the token source for the
// preprocessing engine. In this case this is parameterized
// with the token type.
typedef boost::wave::cpplexer::lex_iterator<
boost::wave::cpplexer::lex_token<> >
lex_iterator_type;
typedef boost::wave::context<
std::string::iterator, lex_iterator_type>
context_type;
context_type ctx(input.begin(), input.end(), "preproc.cpp");
// At this point you may want to set the parameters of the
// preprocessing as include paths and/or predefined macros.
//ctx.add_include_path("...");
//ctx.add_macro_definition("...");
// Get the preprocessor iterators and use them to generate
// the token sequence.
context_type::iterator_type first = ctx.begin();
context_type::iterator_type last = ctx.end();
// The input stream is preprocessed for you during iteration
// over [first, last)
while (first != last) {
std::cout << (*first).get_value();
++first;
}
}
我可以成功编译
g++ -std=c++17 -lboost_thread -lboost_filesystem -lboost_wave source.cpp
但是在运行可执行文件时,我得到了这个错误
terminate called after throwing an instance of 'boost::wrapexcept<boost::wave::preprocess_exception>'
what(): boost::wave::preprocess_exception
Aborted (core dumped)
正如评论中所建议的那样,在更改std::cout << (*first).get_value();
为std::cout << (*first).get_value() << '\n';
明显在 EOF 处引发异常时。纯粹猜测,我尝试\n
在末尾添加,input
程序运行得很好,没有异常。
但是,当我将代码还原为链接示例时,以便input
从文件中读取而不是硬编码,
//std::string input("int main() { std::cout << \"Hello world\"; }");
std::ifstream instream("somefile.cpp");
std::string input(
std::istreambuf_iterator<char>(instream.rdbuf()),
std::istreambuf_iterator<char>());
然后我得到了同样的错误。
一个问题似乎与\n
字符串末尾的缺失有关,因此更改此
std::string input("int main() { std::cout << \"Hello world\"; }");
对此
std::string input("int main() { std::cout << \"Hello world\"; }\n");
似乎可以解决问题。除了问题比这更广泛。实际上,如果我在字符串中添加标题:
std::string input("#include<iostream>\nint main() { std::cout << \"Hello world\"; }\n");
然后我得到同样的失败。最令人惊讶的是,如果我评论该标题:
std::string input("//#include<iostream>\nint main() { std::cout << \"Hello world\"; }\n");
然后程序运行,但输出是:
#line 2 "/home/enrico/preproc.cpp"
int main() { std::cout << "Hello world"; }
我完全不知道它#include<iostream>
是如何变成的#line 2 "/home/enrico/preproc.cpp"
。
解决方案
从技术上讲,没有尾随换行符的 C 源文件是无效的。您必须确保末尾有换行符:
std::string input("int main() { std::cout << \"Hello world\"; }\n");
推荐阅读
- r - 如何解决在CVXR中具有不同基数的指数项的目标函数?
- r - 如何重命名在 r 中使用 str_detect 找到的列?
- python - Python Tkinter 和 Sqlite 出现操作错误,但我完全按照教程进行操作
- c# - C#问题中的斑马打印机批量打印
- nginx - 错误:getaddrinfo ENOTFOUND ingress-nginx.ingress-nginx-controller.svc.cluster.local
- django - 如何改进保存表单的方法
- php - 如何从在线共享点 url 获取文档 uri?
- omnet++ - 在 Omnet++ 中定义和获取/设置全局变量或类类型变量
- apache-flink - 多个 FlinkKinesisProducer 作为数据流的接收器
- python - 如何通过循环创建变量