result = sscanf_s(line.c_str(), "data (%d,%d)", &a, &b);
在上面的代码中,我正在使用 sscanf_s 从给定的字符串 line 中提取两个整数值。在C ++ 11中还有另一种方法,更面向对象吗? (std :: stringstream和/或正则表达式?)
编辑:我尝试了两种解决方案,第一种无效,第二种有效
// solution one (doesn't work)
// let line = "data (3,4)"
std::regex re("data (.*,.*)");
std::smatch m;
if (std::regex_search(line, m, re) )
cout << m[0] << " "<< m[1]; // I get the string "data (3,4) (3,4)"
// solution two (works but is somewhat ugly)
std::string name;
char openParenthesis;
char comma;
char closeParenthesis;
int x = 0, y = 0;
std::istringstream stream(line);
stream >> name >> openParenthesis >> a >> comma >> b >> closeParenthesis;
if( name=="data" && openParenthesis == '(' && comma == ',' && closeParenthesis == ')' )
{
a = x;
b = y;
}
编辑2:在肖恩(Shawn)的输入下,以下内容可以完美工作:
std::regex re(R"(data \(\s*(\d+),\s*(\d+)\))");
std::smatch m;
if (std::regex_search(line, m, re) )
{
a = std::stoi(m[1]);
b = std::stoi(m[2]);
}
答案 0 :(得分:1)
如果不必本身是正则表达式,则可以使用Boost.Spirit。以下是对this example的略微修改,并为您提供了向量中任意数量的逗号分隔的整数。 (这不完全是您所要求的,而是展示了其他可能的方式,而且我也不想花更多的精力来更改示例)。
这适用于迭代器,即字符串和流。它也可以轻松地扩展到更复杂的语法,并且您可以创建独立的语法 objects ,您可以重复使用它们,或者将其组合成更加复杂的语法。 (此处未演示。)
#include "boost/spirit/include/qi.hpp"
#include "boost/spirit/include/phoenix_core.hpp"
#include "boost/spirit/include/phoenix_operator.hpp"
#include "boost/spirit/include/phoenix_stl.hpp"
#include <iostream>
#include <string>
#include <vector>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
template < typename Iterator >
bool parse_data( Iterator first, Iterator last, std::vector< int > & v )
{
bool r = qi::phrase_parse( first, last,
// Begin grammar
(
qi::lit( "data" ) >> '('
>> qi::int_[ phoenix::push_back( phoenix::ref( v ), qi::_1 ) ]
>> *( ',' >> qi::int_[ phoenix::push_back( phoenix::ref( v ), qi::_1 ) ] )
>> ')'
),
// End grammar
ascii::space );
if ( first != last ) // fail if we did not get a full match
{
return false;
}
return r;
}
int main()
{
std::string input = "data (38,4)";
std::vector< int > v;
if ( parse_data( input.begin(), input.end(), v ) )
{
std::cout << "Read:\n";
for ( auto i : v )
{
std::cout << i << "\n";
}
}
else
{
std::cout << "Failed.\n";
}
return 0;
}