/////////////////////////////////////////////////////////////////// // // polygon_input_sscanf.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 return // value of sscanf. Even C++ programmers should become familiar // with sprintf and sscanf (printf and scanf are valuable, too, // but not as often as sprintf and sscanf). Watch out for // array overrun danger when you use sprintf. // /////////////////////////////////////////////////////////////////// #include #include #include #include void trim( string& s ); bool getnextline( istream& in, string& s ); void test_trim(); int main() { string s; int m, n, x, y; // Number of polygons. if( getnextline( cin, s ) ) { if( sscanf( s.c_str(), "%d", &n ) == 1 ) 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 ) ) { if( sscanf( s.c_str(), "%d", &m ) == 1 ) 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 ) ) { if( sscanf( s.c_str(), "%d %d", &x, &y ) == 2 ) 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; }