这种题目,难点不在于代码,而在于
不知道文件格式。根据已有的文件内容猜测其格式,
猜测常常却是错误的。
程序代码:
#include <fstream>
#include <vector>
#include <utility>
#include <string>
#include <sstream>
#include <cassert>
#include <iostream>
using namespace std;
std::vector<unsigned> parse_ADVANCED_FACE( const std::string& body );
unsigned parse_FACE_BOUND( const std::string& body );
std::vector<unsigned> parse_EDGE_LOOP( const std::string& body );
int main( void )
{
vector< std::pair<string,string> > lines;
{
ifstream stepfile( "9.STEP" );
if( !stepfile )
{
cerr << "Failed to open the STEP file.\n";
return 1;
}
for( std::string line; getline(stepfile,line) && line!="DATA;"; );
for( std::string line; getline(stepfile,line) && line!="ENDSEC;"; )
{
char numsign; unsigned idx; char eqsign; string key; string body;
if( getline(getline(istringstream(line)>>numsign>>idx>>eqsign>>ws,key,'('),body) && numsign=='#' && idx!=0 && eqsign=='=' )
{
key.erase( key.find_last_not_of(" \t")+1 );
lines.resize( max(lines.size(),idx) );
assert( lines[idx-1].first.empty() && lines[idx-1].second.empty() );
lines[idx-1] = make_pair(key,body);
}
else assert( false );
}
}
for( size_t i=0; i!=lines.size(); ++i )
{
if( lines[i].first == "ADVANCED_FACE" )
{
std::vector<unsigned> edgenums;
std::vector<unsigned> facenums = parse_ADVANCED_FACE( lines[i].second );
for( size_t j=0; j!=facenums.size(); ++j )
{
size_t pos = facenums[j]-1;
if( pos<lines.size() && (lines[pos].first=="FACE_OUTER_BOUND" || lines[pos].first=="FACE_BOUND") )
{
unsigned bound_begin = parse_FACE_BOUND( lines[pos].second );
if( bound_begin!=0 && bound_begin-1<lines.size() && lines[bound_begin-1].first=="EDGE_LOOP" )
{
std::vector<unsigned> edgenum = parse_EDGE_LOOP( lines[bound_begin-1].second );
edgenums.insert( edgenums.end(), edgenum.begin(), edgenum.end() );
}
else assert( false );
}
else assert( false );
}
cout << '#' << (i+1) << '\t' << lines[i].first << '(' << edgenums.size() << "):";
for( size_t j=0; j!=edgenums.size(); ++j )
cout << "\t#" << edgenums[j];
cout << '\n';
}
}
return 0;
}
std::vector<unsigned> parse_ADVANCED_FACE( const std::string& body )
{
std::vector<unsigned> idxs;
{
size_t a = body.find( '(' );
size_t b = body.find( ')', a );
if( a!=string::npos && b!=string::npos && body.substr(0,a)==" 'NONE', " )
{
istringstream iss( body.substr(a+1,b-a-1) );
for( string field; getline(iss,field,','); )
{
char numsign; unsigned idx;
istringstream iss(field);
if( (iss>>ws>>numsign>>idx>>ws) && iss.eof() && idx!=0 )
{
idxs.push_back( idx );
}
else assert( false );
}
}
else assert( false );
}
return idxs;
}
unsigned parse_FACE_BOUND( const std::string& body )
{
std::vector<unsigned> idxs; // 'NONE', #314, .T. ) ;
{
size_t a = body.find( '#' );
size_t b = body.find( ',', a );
if( a!=string::npos && b!=string::npos && body.substr(0,a)==" 'NONE', " )
{
unsigned idx;
istringstream iss( body.substr(a+1,b-a-1) );
if( (iss>>idx>>ws) && iss.eof() )
{
return idx;
}
}
}
assert( false );
return 0;
}
std::vector<unsigned> parse_EDGE_LOOP( const std::string& body )
{
std::vector<unsigned> idxs;
{
size_t a = body.find( '(' );
size_t b = body.find( ')', a );
if( a!=string::npos && b!=string::npos && body.substr(0,a)==" 'NONE', " )
{
istringstream iss( body.substr(a+1,b-a-1) );
for( string field; getline(iss,field,','); )
{
char numsign; unsigned idx;
istringstream iss(field);
if( (iss>>ws>>numsign>>idx>>ws) && iss.eof() && idx!=0 )
{
idxs.push_back( idx );
}
else assert( false );
}
}
else assert( false );
}
return idxs;
}
输出:
#28 ADVANCED_FACE(4): #56 #193 #338 #214
#77 ADVANCED_FACE(3): #212 #187 #51
#108 ADVANCED_FACE(6): #297 #183 #142 #29 #161 #239
#130 ADVANCED_FACE(4): #68 #27 #233 #308
#185 ADVANCED_FACE(4): #179 #208 #44 #303
#211 ADVANCED_FACE(4): #78 #324 #320 #61
#235 ADVANCED_FACE(3): #154 #281 #60
#259 ADVANCED_FACE(4): #234 #106 #24 #153
#307 ADVANCED_FACE(4): #71 #206 #279 #169
#329 ADVANCED_FACE(4): #104 #312 #132 #263