将字符解析为std :: map< char,int>使用boost :: qi
我试图将一系列字符解析为“”,“”,sTD :: map< char,int>对键是字符的对,而值只是分析字符的数量。 例如,如果输入是
a,b,c
地图应包含对的,
(a,1) , (b,2) , (c,3)
则是我使用的代码:
namespace myparser
{
std::map<int, std::string> mapping;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
int i = 0;
template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last, std::map<char,int>& v)
{
using qi::double_;
using qi::char_;
using qi::phrase_parse;
using qi::_1;
using ascii::space;
using phoenix::push_back;
bool r = phrase_parse(first, last,
// Begin grammar
(
char_[v.insert(std::make_pair(_1,0)]
>> *(',' >> char_[v.insert(std::make_pair(_1,0)])
)
,
// End grammar
space);
if (first != last) // fail if we did not get a full match
return false;
return r;
}
//]
}
然后,我尝试以这样的方式打印这对:
int main() {
std::string str;
while (getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
std::map<char,int> v;
std::map<std::string, int>::iterator it = v.begin();
if (myparser::parse_numbers(str.begin(), str.end(), v))
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << str << " Parses OK: " << std::endl;
while (it != v.end())
{
// Accessing KEY from element pointed by it.
std::string word = it->first;
// Accessing VALUE from element pointed by it.
int count = it->second;
std::cout << word << " :: " << count << std::endl;
// Increment the Iterator to point to next entry
it++;
}
std::cout << "\n-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
}
return 0;
}
我是初学者,我不知道如何修复此代码。我还想使用字符串而不是字符,因此我输入了一系列由“”隔开的字符串,然后将它们存储在类似于上面提到的类似的地图中。感谢任何帮助!
I am trying to parse a sequence of characters separated by a "," into an std::map<char,int> of pairs where the key is the character and the value just the a count of parsed characters.
For example, if the input is
a,b,c
The map should contain the pairs:
(a,1) , (b,2) , (c,3)
Here's the code I am using :
namespace myparser
{
std::map<int, std::string> mapping;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
int i = 0;
template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last, std::map<char,int>& v)
{
using qi::double_;
using qi::char_;
using qi::phrase_parse;
using qi::_1;
using ascii::space;
using phoenix::push_back;
bool r = phrase_parse(first, last,
// Begin grammar
(
char_[v.insert(std::make_pair(_1,0)]
>> *(',' >> char_[v.insert(std::make_pair(_1,0)])
)
,
// End grammar
space);
if (first != last) // fail if we did not get a full match
return false;
return r;
}
//]
}
Then I try to print the pair in main like this:
int main() {
std::string str;
while (getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
std::map<char,int> v;
std::map<std::string, int>::iterator it = v.begin();
if (myparser::parse_numbers(str.begin(), str.end(), v))
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << str << " Parses OK: " << std::endl;
while (it != v.end())
{
// Accessing KEY from element pointed by it.
std::string word = it->first;
// Accessing VALUE from element pointed by it.
int count = it->second;
std::cout << word << " :: " << count << std::endl;
// Increment the Iterator to point to next entry
it++;
}
std::cout << "\n-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
}
return 0;
}
I am a beginner and I don't know how to fix this code . I also want to use strings instead of characters so I enter a sequence of strings separated by a "," and store them in a map similar to the one mentioned above. I would appreciate any help !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不能在凤凰城延期演员之外使用凤凰座持有人。例如,
std :: make_pair的类型(qi :: _ _ 1,0)
isstd :: pair&lt&lt&lt; boost :: Phoenix :: Actor&lt; boost :: Phoenix :: phoenix :: gright&lt; lt; 0&gt; gt; &gt;,int&gt;
。没有什么可以与这样的事情互动。当然不是
std :: map&lt; :: insert
。您需要做的是将所有操作作为凤凰演员作为语义动作。
您可以:
查看 live
然后, 正确的。
我花了半个小时的时间来调试为什么它不起作用。为什么这么难?
这是因为有人发明了整个meta-dsl来编写“正常的C ++”,但执行得分。当发生这种情况时,它非常整洁,但它是所有漏水的母亲,剃须刀锋利的边缘。
那么,什么新功能?使用C ++ 11您可以:
live noreferrer“> live C ++ 17:
live live
可能想 count 事情,所以,也许使用
noreflow noreferrer“> live < /a>
此时,您可以切换到Spirit X3(需要C ++ 14):
live
现在,让我们简化。
p&gt;&gt; *(',','&gt;&gt; p)
只是说p%','
的一种笨拙的方式:live
您想要单词,而不是字符:
live
打印
注意
x3 :: Space
(例如QI :: Space :: Space
和qi :: ascii :: Space
上面)。You cannot use Phoenix place holders outside Phoenix deferred actors. E.g. the type of
std::make_pair(qi::_1, 0)
isstd::pair<boost::phoenix::actor<boost::phoenix::argument<0>>, int>
.Nothing interoperates with such a thing. Certainly not
std::map<>::insert
.What you'd need to do is wrap all the operations in semantic actions as Phoenix actors.
Then you can:
See it Live
Easy peasy. Right.
I spent half an hour on that thing debugging why it wouldn't work. Why is this so hard?
It's because someone invented a whole meta-DSL to write "normal C++" but with defferred execution. Back when that happened it was pretty neat, but it is the mother of all leaky abstractions, with razor sharp edges.
So, what's new? Using C++11 you could:
Live
Or using c++17:
Live
On a tangent, you probably wanted to count things, so, maybe use
Live
By this time, you could switch to Spirit X3 (which requires C++14):
Live
Now finally, let's simplify.
p >> *(',' >> p)
is just a clumsy way of sayingp % ','
:Live
And you wanted words, not characters:
Live
Prints
Note the behaviour of the
x3::space
(likeqi::space
andqi::ascii::space
above).