C++;解析输入 我需要解析一个C++ STDIN输入,它看起来像这样:
N M(对) 如果N>0&&M>0,则随后将出现M对。这是一个单行输入,所以我不知道怎么做 我有一些解决办法,但有些东西告诉我这不是最好的C++;解析输入 我需要解析一个C++ STDIN输入,它看起来像这样:,c++,c,C++,C,N M(对) 如果N>0&&M>0,则随后将出现M对。这是一个单行输入,所以我不知道怎么做 我有一些解决办法,但有些东西告诉我这不是最好的 void input(){ int a[100][2]; int n,m; char ch; cin >> n >> m; for ( int i = 0; i < m; i++) { cin >> ch >> a[i][0]>> ch&
void input(){
int a[100][2];
int n,m;
char ch;
cin >> n >> m;
for ( int i = 0; i < m; i++) {
cin >> ch >> a[i][0]>> ch>> a[i][1]>>ch;
}
cout << n << " " << m << " \n";
for ( int i=0; i < m; i++ ) {
cout << "(" << a[i][0] << " ," << a[i][1] << ")";
}
}
void输入(){
INTA[100][2];
int n,m;
char ch;
cin>>n>>m;
for(int i=0;i>ch>>a[i][0]>>ch>>a[i][1]>>ch;
}
cout由于应用程序的输入数据永远不可信,因此必须添加错误检查,以确保提供的数据确实有效(否则,应用程序的结果在解析时可能会出错)
处理此类错误的“C++方法”是在负责解析数据的函数出现问题时抛出异常
然后,此函数的调用方将调用包装在try-catch块中,以捕获可能出现的错误
使用用户定义的类型。。
定义自己的类型来保存数据对将极大地提高代码的可读性,下面的实现和本文后面的实现的输出是相同的
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
通常,我不建议只使用大写字母命名非常量变量,但为了更清楚地说明哪个变量包含与输入描述相同的名称
由于应用程序的输入数据永远不可信,因此添加错误检查以确保所提供的数据确实有效非常重要(否则,应用程序的结果在解析时可能会出错)
处理此类错误的“C++方法”是在负责解析数据的函数出现问题时抛出异常
然后,此函数的调用方将调用包装在try-catch块中,以捕获可能出现的错误
使用用户定义的类型。。
定义自己的类型来保存数据对将极大地提高代码的可读性,下面的实现和本文后面的实现的输出是相同的
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
通常,我不建议只使用大写字母命名非常量变量,但为了更清楚地说明哪个变量包含与输入描述相同的名称
如果要求操作的数据都在一行上,那么最好的技术可能是将该行读入字符串,然后解析从输入字符串初始化的stringstream
您应该考虑是否需要验证括号和逗号是否真的是括号和逗号-如果输入为:
23 2 @3;8= % 7 % 12 %
您的代码会接受目前的有效性。如果要求操作的数据都在一行中,那么最好的技术可能是将该行读入字符串,然后解析从输入字符串初始化的stringstream
您应该考虑是否需要验证括号和逗号是否真的是括号和逗号-如果输入为:
23 2 @3;8= % 7 % 12 %
您的代码会接受这一点,认为它目前是有效的。对于这种情况,规范的解决方案是为
并为其实现一个>
运算符。类似于:
class Pair
{
int first;
int second;
public:
Pair( int first, int second );
// ...
};
std::istream&
operator>>( std::istream& source, Pair& object )
{
char open;
char separ;
char close;
int first;
int second;
if ( source >> open >> first >> separ >> second >> close
&& open == '(' && separ == ',' && close == ')' ) {
object = Pair( first, second );
} else {
source.setstate( std::ios_base::failbit );
}
return source;
}
鉴于此,要读取该文件:
std::string line;
while ( std::getline( source, line ) ) {
std::istringstream l( line );
int n;
int m;
std::vector<Pair> pairs;
l >> n >> m;
if ( !l ) {
// Syntax error...
}
Pair p;
while ( l >> p ) {
pairs.push_back( p );
}
if ( ! l.eof() ) {
// Error encountered somewhere...
}
// Other consistency checks...
}
std::字符串行;
while(std::getline(源,行)){
std::istringstream l(线);
int n;
int m;
std::向量对;
l>>n>>m;
如果(!l){
//语法错误。。。
}
对p;
while(l>>p){
配对。推回(p);
}
如果(!l.eof()){
//在某处遇到错误。。。
}
//其他一致性检查。。。
}
对于这种情况,规范的解决方案是为
并为其实现一个>
运算符。类似于:
class Pair
{
int first;
int second;
public:
Pair( int first, int second );
// ...
};
std::istream&
operator>>( std::istream& source, Pair& object )
{
char open;
char separ;
char close;
int first;
int second;
if ( source >> open >> first >> separ >> second >> close
&& open == '(' && separ == ',' && close == ')' ) {
object = Pair( first, second );
} else {
source.setstate( std::ios_base::failbit );
}
return source;
}
鉴于此,要读取该文件:
std::string line;
while ( std::getline( source, line ) ) {
std::istringstream l( line );
int n;
int m;
std::vector<Pair> pairs;
l >> n >> m;
if ( !l ) {
// Syntax error...
}
Pair p;
while ( l >> p ) {
pairs.push_back( p );
}
if ( ! l.eof() ) {
// Error encountered somewhere...
}
// Other consistency checks...
}
std::字符串行;
while(std::getline(源,行)){
std::istringstream l(线);
int n;
int m;
std::向量对;
l>>n>>m;
如果(!l){
//语法错误。。。
}
对p;
while(l>>p){
配对。推回(p);
}
如果(!l.eof()){
//在某处遇到错误。。。
}
//其他一致性检查。。。
}
对于此类任务,我更喜欢:
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <string>
#include <iostream>
struct input {
int x, y;
typedef std::pair<int, int> pair;
std::vector< pair > pairs;
};
BOOST_FUSION_ADAPT_STRUCT(
input,
(int, x)
(int, y)
(std::vector< input::pair >, pairs))
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template<typename Iterator>
struct input_parser : qi::grammar<Iterator, input(), ascii::space_type> {
input_parser() : input_parser::base_type(start) {
// two integers followed by a possibly empty list of pairs
start = qi::int_ >> qi::int_ >> *pair;
// a tuple delimited by braces and values separated by comma
pair = '(' >> qi::int_ >> ',' >> qi::int_ >> ')';
}
qi::rule<Iterator, input(), ascii::space_type> start;
qi::rule<Iterator, input::pair(), ascii::space_type> pair;
};
template<typename Iterator>
void parse_and_print(Iterator begin, Iterator end) {
input x;
input_parser<Iterator> p;
bool r = qi::phrase_parse(begin, end, p, ascii::space, x);
if(!r) {
std::cerr << "Error parsing" << std::endl;
return;
}
std::cout << "Output" << std::endl;
std::cout << "x: " << x.x << std::endl;
std::cout << "y: " << x.y << std::endl;
if(x.pairs.empty()) {
std::cout << "No pairs.";
} else {
for(std::vector<input::pair>::iterator it = x.pairs.begin();
it != x.pairs.end(); ++it) {
std::cout << "(" << it->first << ',' << it->second << ") ";
}
}
std::cout << std::endl;
}
int main()
{
namespace qi = boost::spirit::qi;
std::string input1 = "0 0";
std::string input2 = "2 1 (0,1)";
std::string input3 = "2 0";
std::string input4 = "5 8 (0,1) (1,3) (2,3) (0,2) (0,1) (2,3) (2,4) (2,4)";
parse_and_print(input1.begin(), input1.end());
parse_and_print(input2.begin(), input2.end());
parse_and_print(input3.begin(), input3.end());
parse_and_print(input4.begin(), input4.end());
return 0;
}
#包括
#包括
#包括
#包括
#包括
结构输入{
int x,y;
typedef std::对;
std::向量对;
};
增强融合适应结构(
输入,
(int,x)
(国际,y)
(std::vector,pairs))
名称空间qi=boost::spirit::qi;
名称空间ascii=boost::spirit::ascii;
模板
结构输入语法分析器:qi::grammar{
输入语法分析器():输入语法分析器::基本语法类型(开始){
//两个整数,后跟可能为空的对列表
start=qi::int\u>>qi::int\u>>*对;
//由大括号和逗号分隔的值分隔的元组
pair='('>>qi::int_>>,'>>qi::int_>>);
}
qi::规则开始;
qi:规则对;
};
模板
void parse_和_print(迭代器开始、迭代器结束){
输入x;
输入语法分析器p;
bool r=qi::短语解析(开始、结束、p、ascii::空格,x);
if(!r){
我更喜欢这样的任务:
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <string>
#include <iostream>
struct input {
int x, y;
typedef std::pair<int, int> pair;
std::vector< pair > pairs;
};
BOOST_FUSION_ADAPT_STRUCT(
input,
(int, x)
(int, y)
(std::vector< input::pair >, pairs))
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template<typename Iterator>
struct input_parser : qi::grammar<Iterator, input(), ascii::space_type> {
input_parser() : input_parser::base_type(start) {
// two integers followed by a possibly empty list of pairs
start = qi::int_ >> qi::int_ >> *pair;
// a tuple delimited by braces and values separated by comma
pair = '(' >> qi::int_ >> ',' >> qi::int_ >> ')';
}
qi::rule<Iterator, input(), ascii::space_type> start;
qi::rule<Iterator, input::pair(), ascii::space_type> pair;
};
template<typename Iterator>
void parse_and_print(Iterator begin, Iterator end) {
input x;
input_parser<Iterator> p;
bool r = qi::phrase_parse(begin, end, p, ascii::space, x);
if(!r) {
std::cerr << "Error parsing" << std::endl;
return;
}
std::cout << "Output" << std::endl;
std::cout << "x: " << x.x << std::endl;
std::cout << "y: " << x.y << std::endl;
if(x.pairs.empty()) {
std::cout << "No pairs.";
} else {
for(std::vector<input::pair>::iterator it = x.pairs.begin();
it != x.pairs.end(); ++it) {
std::cout << "(" << it->first << ',' << it->second << ") ";
}
}
std::cout << std::endl;
}
int main()
{
namespace qi = boost::spirit::qi;
std::string input1 = "0 0";
std::string input2 = "2 1 (0,1)";
std::string input3 = "2 0";
std::string input4 = "5 8 (0,1) (1,3) (2,3) (0,2) (0,1) (2,3) (2,4) (2,4)";
parse_and_print(input1.begin(), input1.end());
parse_and_print(input2.begin(), input2.end());
parse_and_print(input3.begin(), input3.end());
parse_and_print(input4.begin(), input4.end());
return 0;
}
#包括
#包括
#包括
#包括
#包括
结构输入{
int x,y;
typedef std::对;
std::向量对;
};
增强融合适应结构(
输入,
(int,x)
(国际,y)
(std::vector,pairs))
名称空间qi=boost::spirit::qi;
名称空间ascii=boost::spirit::ascii;
模板
结构输入语法分析器:qi::grammar{
输入语法分析器():输入语法分析器::基本语法类型(开始){
//两个整数,后跟可能为空的对列表
start=qi::int\u>>qi::int\u>>*对;
//由大括号和逗号分隔的值分隔的元组
pair='('>>qi::int_>>,'>>qi::int_>>);