C++ Help Thu Sep 28 19:32:01 EDT 2006 Include Files ------- ----- The following are typical includes in modern C++: #include #include #include #include #include #include using namespace std; It is common to have a conflict with some name defined in the includes. E.g., you may have trouble naming a global variable `time'. To fix this, change the name of your variable. A simple way of doing this is to put the following right after the includes: #define time Time If you want your code to last as include files change, replace the using statement above with statements such as the following: using std::cin; using std::cout; using std::endl; Program Structure and Debugging ------- --------- --- --------- Typical program structure including end of file detect- ion and debugging is: #include ... . . . bool debug; #define dout if ( debug ) cout int main ( int argc ) { // argc-1 == number of program arguments. debug = ( argc > 1 ); . . . . while ( true ) { . . . . . cin >> x >> y >> z; if ( cin.eof() ) break; . . . . . dout << . . . . . . . . } } After reading with `cin >> ...', cin.eof() is true if and only if an end of file has occurred on cin. No other error indication is given. Note that `cin.eof()' is normally false after successfully reading some value, as the input is still before the end of the line containing the value. Many problems require you to detect certain input values as end of data markers, instead of looking for eof. E.g., the problem might specify that x, y, and z are all 0 to indicate end of data, in which case you replace the above `if' statement by if ( x == 0 && y == 0 && z == 0 ) break; Above `dout' behaves just like `cout' except no output is produced unless your program is called with an argument. One must be careful, however, to remember that `dout' contains an `if' statement and cannot be followed directly by an `else if'; i.e., the following will NOT work: if (...) dout << ...; else if ... Put {} brackets around `dout << ...;' in this situation. Debugging is best done with information printed by `dout', and not with a debugger like `gdb'. The excep- tion is debugging programs that crash or go into an infinite loop, which is best done with a debugger. It is also a good idea to use `assert' statements to check that assumptions you have made are valid during actual program execution. Numeric Constants ------- --------- The following code imports useful constants, which are the minimum and maximum values of various number types, and the values of PI and E. INCLUDE IMPORTS #include int INT_MAX; int INT_MIN; long LONG_MAX; long LONG_MIN; unsigned long ULONG_MIN; #include double DBL_MAX; double DBL_MIN; float FLT_MAX; float FLT_MIN; #include double M_PI; double M_E; Fixed Width Output ------------------ The following is useful for producing fixed width format numbers. To output a right adjusted integer I in N columns use: cout << setw (N) << I; Setw sets the width of the next output; but each output resets this to 0 so you must reset the width just before outputting each N column number. The width of 0 means `use as many columns as necessary'. To output a right adjusted floating point number F in N columns with P decimal places use: cout << setiosflags ( ios::showpoint | ios::fixed ); cout << setprecision (P); cout << setw (N) << F; The precision P and flags do not get reset after the number is output. They can be reset to defaults by cout << resetiosflags ( ios::showpoint | ios::fixed ); cout << setprecision (6); Sometimes you are asked to use `0' as a high order fill character, instead of ` ', or to output in hexadecimal or octal instead of decimal. This can be done with cout << setfill ('0'); // Set fill character. cout << setfill (' '); // Reset fill character. cout << hex; // Set base to 16. cout << dec; // Set base to 10. cout << oct; // Set base to 8. To use setw etc. you need to: #include You may also need using std::setw; using std::hex; using std::dec; using std::setprecision; using std::ios; etc. However, somewhat counter intuitively using std::setiosflags; using std::resetiosflags; do not work and are not needed. Character Input --------- ----- You can use the following for character input: int c = cin.get(); // Get next character. int c = cin.peek(); // Return next character // without skipping over it. These return EOF for end of file. Inputting Lines --------- ----- To input a line use the getline function, as in char buffer [SOME_SIZE]; cin.getline ( buffer, sizeof ( buffer ) ); The new line at the end of the line is NOT stored in the buffer; a NUL character is stored at the end of the line in the buffer. Do NOT try to use the `get' function in place of `getline': its behavior is similar but it does NOT skip over the new line in the input stream, and therefore after reading the first line it reads empty lines forever. If you use non-line-oriented code to input a value V, you CANNOT then use `getline' to get a following line, unless you first skip by the end of line after V. Failing to do this causes `getline' to read an empty line, consisting of just the line feed after V. Typical correct code is: int x; cin >> x; // Does not skip line end. while ( cin.get() != '\n' ); cin.getline ( ... ); Parsing Lines ------- ----- You can parse a line after it is input by code such as #include using std::istringstream; istringstream in ( buffer ); Now `in' is an input stream whose input is taken from the buffer (actually, the input is copied from the buffer into another buffer internal to the instring- stream when the latter is created). Here in.eof() will be true at the end of the string. This is likely to be a problem because immediately after reading a number at the end of the buffer in.eof() will be true. To compensate, check for eof BEFORE reading each value by first executing `in >> ws' to skip past whitespace, then testing in.eof(), and only then reading the value. Typical code is: in >> ws; if ( in.eof() ) break; in >> x; Writing Strings ------- ------- Strings can be written using: #include using std::ostringstream; ostringstream out; . . . out << . . . out << ends; const char * s = out.str().data(); cout << s; Here `out' is an output stream whose output is written into an INTERNAL buffer (you CANNOT make a stream that writes into your buffer). You can get the starting address of a string that contains the contents of the internal buffer with `out.str().data()'. Before doing this, use `out << ends' to write a NUL into the buffer. You can also use `cout << out.str()' to write the internal buffer to `cout' directly, but do NOT use `out << ends' in this case, as the NUL will be written to `cout' if you do. Writing Your Own << And >> Operators ------- ---- --- -- --- -- --------- It is often convenient to define your own << operator to output something. Some examples are: using std::ostream; ostream & operator << ( ostream & out, mytype & value ) { . . . out << . . . . . . return out; } Suppose you want to output integers in a distinctive format. A simple way is struct myformat { int value; myformat ( int value ) : value ( value ) {} }; ostream & operator << ( ostream & out, myformat s ) { out << ( ... s.value ... ); . . . return out; } . . . cout << myformat ( 99 ); Here we have invented a typed structure to encapsulate the value when it is to be printed. Note the argument to << may NOT be `myformat & s' because here s is not constant, and in use the `myformat' value is a temporary and temporaries are read-only. Input operators can be define by: using std::istream; istream & operator >> ( istream & in, mytype & value ) { . . . in >> . . . . . . return in; } STL API Documentation --- --- ------------ Standard Template Library (STL) API documentation is usually available on-line during a formal contest. The command to access it is: stlhelp In a formal contest, you should NOT use other means to access such documentation, as using the internet is a violation of formal contest rules. File: c++ Author: Bob Walton Date: See top of file. The authors have placed this file in the public domain; they make no warranty and accept no liability for this file. RCS Info (may not be true date or author): $Author: walton $ $Date: 2006/09/28 23:35:34 $ $RCSfile: c++,v $ $Revision: 1.13 $