/////////////////////////////////////////////////////////////////// // // polygon_input_stringstream.cpp // // Jeff Ondich, 5/30/03 // // This shows one approach to taking input from a polygon // file formatted as described in the polygon intersection // assignment for CS257, Spring 2003. The file format is: // // [number of polygons] // [name of first polygon] // [number of vertices in first polygon] // [x space y coordinates for first vertex] // ... // [x space y coordinates for last vertex] // [name of second polygon] // ... // // For example: // // 1 // My right triangle // 3 // 100 100 // 200 200 // 100 200 // // The format also allows comment lines, starting with #. // This program adds a bit of robustness by also allowing blank // lines and spaces preceding the #. // // This program doesn't do anything sensible other than complain // when it encounters a violation of the format. // // The format is verified (as far as it goes) using the state // of an istringstream object attached to the current line of // text. If an extraction operation fails, the state of the // istringstream goes bad, and in a boolean context like this: // // if( sin >> n ) // // the extraction will evaluate to false. // // Unfortunately, the implementation of stringstreams on our // Linux machines gives a segmentation fault when I call // istringstream::str. I've used test code from an authoritative // web site, and it fails in the same way as mine does. I have // also used this code here on a FreeBSD system with g++, and // everything worked fine. I hope to figure out the problem // soon, but since we are also seeing memory leaks with the // string class, I just think our STL implementation is buggy. // /////////////////////////////////////////////////////////////////// #include #include #include #include void trim( string& s ); bool getnextline( istream& in, string& s ); void test_trim(); int main() { string s; istringstream sin; int m, n, x, y; // Number of polygons. if( getnextline( cin, s ) ) { sin.str( s ); if( sin >> n ) cout << "There are " << n << " polygons." << endl; else cout << "Trouble reading number of polygons." << endl; } // For each polygon... for( int j=0; j < n; j++ ) { // Name. if( getnextline( cin, s ) ) cout << "Polygon " << j << " is named: " << s << endl; else cout << "Trouble reading name of polygon " << j << endl; // Number of vertices. if( getnextline( cin, s ) ) { sin.str( s ); if( sin >> m ) cout << "There are " << m << " vertices." << endl; else cout << "Trouble reading number of vertices." << endl; } // Vertices. cout << "Vertices:" << endl; for( int k=0; k < m; k++ ) { if( getnextline( cin, s ) ) { sin.str( s ); if( sin >> x >> y ) cout << "(" << x << "," << y << ")" << endl; else cout << "Trouble reading vertex." << endl; } } } return 0; } // Just a little test for my trim function. void test_trim() { string s; s = " \t howdy\t\n\r \t"; trim( s ); cout << "[" << s << "] should be [howdy]" << endl; s = " "; trim( s ); cout << "[" << s << "] should be []" << endl; s = "pig"; trim( s ); cout << "[" << s << "] should be [pig]" << endl; s = ""; trim( s ); cout << "[" << s << "] should be []" << endl; } // Removes all white space (as defined by isspace()) from the beginning // and end of the string. void trim( string& s ) { int j; for( j=s.length()-1; j >=0 && isspace(s[j]); j-- ) { } s.erase( j + 1); int len = s.length(); for( j=0; j < len && isspace(s[j]); j++ ) { } s.erase( 0, j ); } // Skips over comment lines (including those that begin with white space // followed by a #), blank lines, and all-white-space lines. Returns in s // the first line that is none of these. Returns false if there is no // such line remaining in the input, and true if there is. bool getnextline( istream& in, string& s ) { while( getline( in, s ) ) { trim( s ); if( s.length() > 0 && s[0] != '#' ) return true; } return false; }