gpt4 book ai didi

c++ - boost 分词器但保留定界符

转载 作者:行者123 更新时间:2023-11-30 01:48:50 25 4
gpt4 key购买 nike

也许这很容易,但我自己找不到答案。

我想使用 boost::tokenizer 但保留字符串的分隔符

我的字符串是一串像这样的数字

"1.00299 344.2221-25.112-33112"

结果应该是:

"1.00299"  "344.2221"  "-25.112" "-33112"

我知道它看起来有点奇怪,但文件就是这样写的。

另一个问题有点复杂,因为有些字符串是这样的:

"1.00299E+45 344.22E-21-25.112E+11-3.31E-12" 

应该是:

"1.00299E+45" "344.22E-21" "-25.112E+11"  "-3.31E-12"`

任何帮助将不胜感激

问候

Julia

最佳答案

让我们实现一个requote 操纵器,它允许您执行以下操作:

#include "requote.hpp"
#include <iostream>

int main() {
std::cout << requote(std::cin);
}

现在 requote.hpp 里有什么?

#include <istream>

struct requote {
requote(std::istream& is) : _is(is.rdbuf()) {}

friend std::ostream& operator<<(std::ostream& os, requote const& manip) {
return manip.call(os);
}

private:
std::ostream& call(std::ostream& os) const;
mutable std::istream _is;
};

Note: We instantiate a private istream using the same streambuf, so the stream state is isolated.

所有的魔法都在 call() 中。以下是我如何使用 Boost Spirit 执行此操作。 copy_out 的复杂性在于确保这两者

  • 我们不会更改输入表示的任何部分(精度、格式),除了引用
  • 尽可能高效(我们不构造任何临时字符串,异常用于解析异常)
#include "requote.hpp"

namespace /*anon*/ {
struct copy_out {
mutable std::ostreambuf_iterator<char> out;

//template <typename...> struct result { typedef void type; };
template <typename R> void operator()(R const& r) const {
*out++ = '"';
out = std::copy(r.begin(), r.end(), out);
*out++ = '"';
*out++ = ' ';
}
};
}

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

std::ostream& requote::call(std::ostream& os) const {
boost::phoenix::function<copy_out> copy_out_({os});
using namespace boost::spirit::qi;

boost::spirit::istream_iterator f(_is >> std::noskipws), l;
bool ok = phrase_parse(f,l,
*('"' > *raw[long_double][copy_out_(_1)] > '"') [boost::phoenix::ref(os)<<'\n'],
space
);

if (ok && f==l)
return os;

throw std::runtime_error("parse error at '" + std::string(f,l) + "'");
}

演示

Self-Contained On Coliru

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

struct requote {
requote(std::istream& is) : _is(is.rdbuf()) {}

friend std::ostream& operator<<(std::ostream& os, requote const& manip) {
return manip.call(os);
}

private:
std::ostream& call(std::ostream& os) const {
boost::phoenix::function<copy_out> copy_out_({os});
using namespace boost::spirit::qi;

boost::spirit::istream_iterator f(_is >> std::noskipws), l;
bool ok = phrase_parse(f,l,
*('"' > *raw[long_double][copy_out_(_1)] > '"') [boost::phoenix::ref(os)<<'\n'],
space
);

if (ok && f==l)
return os;

throw std::runtime_error("parse error at '" + std::string(f,l) + "'");
}

struct copy_out {
mutable std::ostreambuf_iterator<char> out;

//template <typename...> struct result { typedef void type; };
template <typename R> void operator()(R const& r) const {
*out++ = '"';
out = std::copy(r.begin(), r.end(), out);
*out++ = '"';
*out++ = ' ';
}
};
mutable std::istream _is;
};

#include <iostream>
int main() {
std::cout << requote(std::cin);
}

问题样本的输出:

"1.00299" "344.2221" "-25.112" "-33112" 
"1.00299E+45" "344.22E-21" "-25.112E+11" "-3.31E-12"

关于c++ - boost 分词器但保留定界符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29832534/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com