7/24/2018
C/C++ Programming for Engineers: Streams and Arguments
John T. Bell
Department of Computer Science University of Illinois, Chicago
Review
Given the following input: A. blank ( empty string ) Every one is great. B. is great. That's right. What does the following get into str2? C. great. cin >> str0; cin >> str1; D.That’s right getline(cin, tmpStr); getline(cin, str2); E. Error. str2 is unaffected.
2
1 7/24/2018
The Stream Concept
• In C++, a “stream” is a class, encapsulating support for a flow of information. – Input streams, “istream”s, flow information into a variable, from some other source. – Output streams, “ostream”s, flow information out of a program, to some other destination. – Sources and destinations may include the keyboard, screen, data files, or memory buffers.
3
Standard Streams
The following streams are automatically available, when you #include
4
2 7/24/2018
cout Versus cerr
• Normally data sent to either cout or cerr both go to the screen. • However either stream may be redirected independently of the other. • Technically only “results” should be sent to cout; All other output ( e.g. diagnostics, questions, etc. ) should be sent to cerr. • cout is also buffered, whereas cerr is direct.
5
Buffered Output
• Because of the overhead involved in sending individual characters out to hardware, cout normally buffers data until there is enough to be worth sending to the device. • The flush( ) method ( e.g. cout.flush( ) ) and endl force buffers to be flushed. ( not “\n” ) • Unflushed buffers may be lost in a crash. • cerr is unbuffered - Data goes directly to HW.
6
3 7/24/2018
The << Operator
• Technically the << operator is a method, defined in the ostream class for standard types. • The method returns the ostream by reference, allowing daisy chaining: – cout << prompt << x; ( cout << prompt ) << x; • Advanced programmers can define the << operator for specialty data types that they create. E.g. cout << myAirplane << endl;
7
istreams (cin) and the >> Operator
• istreams define the >> operator for all standard types. (Programmers can add more.) • The >> operator reads characters from stdin and converts to the proper data type for storage. E.g. ‘3’ ‘.’ ‘1’ ‘4’ ‘1’ ‘5’ ‘9’ stores PI • >> can also daisy chain: cin >> x >> y >> z; • When reading strings, >> reads up to the next “whitespace” character. ( space, tab, newline ) • The getline( ) method will read in entire lines.
8
4 7/24/2018
Formatting of ostreams
• There are a number of manipulators that can be added into output streams, in order to format the following data. • #include
9
Floating Point Manipulators
Manipulator Description Example Use fixed-point notation. fixed 12.34 From
If stream has not been manipulated to fixed or scientific: p=3 yields 12.3 setprecision(p) Sets max number of digits in number p=5 yields 12.34
If stream has been manipulated to fixed or scientific: fixed: p=1 yields 12.3 Sets max number of digits in fraction only (after the decimal point). scientific: p=1 yields 1.2e+01 From
Even if fraction is 0, show decimal point and trailing 0s. For 99.0 with precision=2 and fixed: showpoint Opposite is noshowpoint. 99 (default or noshowpoint) From
10
5 7/24/2018
Alignment Manipulators
Manipulator Description Example (for item "Amy")
Sets the number of characters for the next output item only (does not persist, in contrast to other manipulators). For n=7: setw(n) By default, the item will be right-aligned, and filled with spaces. “ Amy" From
Sets the fill to character c. For c='*': setfill(c) From
11
Additional Manipulators
Manipulator Description Inserts a newline character '\n' into the output buffer, endl and informs the system to flush the buffer. From
12
6 7/24/2018
printf( )
• printf( ) is the “print formatted” function from C, inherited by C++. • It is both more powerful and more complicated to use than stream manipulators. • int printf( const char * format, . . . ); – First argument is a C-style character string, containing format specifiers denoted by %. – Each time a format specifier is encountered, printf( ) processes another input data argument. – http://www.cplusplus.com/reference/cstdio/printf/
13
The Form of a Format Specifier
• %[flags][width][.precision][length]specifier – flags are modifiers, e.g. left or right justified – width is the total width of the field, including all characters, signs, decimal points, and spaces. – precision is the number of digits right of the decimal point – specifier indicates the type of data: • %d = decimal integer • %f = floating point ( floats, doubles ) • %c = character • %e %E - Exponential notation • %s = string • %g %G - Uses %f/F or %e/E as fits.
14
7 7/24/2018
Review
Given that “temp” is a double with value 98.63, which would cause the output to appear as "9.86e+01"? A. cout << fixed; B. cout << setprecision( 2 ); C. cout << setprecision( 3 ); D. cout << scientific << setprecision( 2 ); E. cout << scientific << setprecision( 3 );
15
Preview
Suppose you have a C++ ifstream variable named “fin” that has been successfully connected to a data file, and that there is an integer in the file ready to be read. How can you read in the integer into the variable “ndata”? A. fin << ndata; B. fin >> ndata; C. ndata << fin; D. fin.read( ndata ); E. fscanf( fin, “%d”, &ndata );
16
8 7/24/2018
Other Types of Streams
• File streams and string streams are special types of I/O streams, transferring data to/from data files and memory buffers respectively. • These special streams provide all the functionality of regular streams ( see next slide ), plus some additional features.
17
The Stream Class Hierarchy
Classes lower in the diagram are more specialized versions of those above them. They “inherit” properties from their “parents”, and then
istringstream ostringstream add additional features and An ifstream IS an istream. Anything you can do with an functionalities. istream you can also do with an ifstream.
18
9 7/24/2018
File Streams
• #include
19
Reading in File Names
• The “string” data type must be converted to C-style character strings for pass to open( ):
string filename; ifstream infile; cerr << “Please enter file name: “; cin >> filename; infile.open( filename.c_str( ) );
20
10 7/24/2018
Using File Streams
• Once file streams are created and connected to open files, they are used the same as any other iostreams, e.g. just like cin and cout: ifstream infile( “myInFile.txt” ); // check ! ofstream outfile( “myOutFile.txt” ); // “ double x; infile >> x; outfile << “x = “ << x << “, x^2 = “ << x * x << endl;
21
Checking Stream Conditions, etc.
The following boolean stream methods check error state. E.g. for stream “infile”, check infile.good( )
Function Meaning good( ) True when there are no errors. True when the end-of-file is reached on extraction. eof( ) Occurs only when attempting to read past end of file. fail( ) True when a logical error occurs on extraction or insertion. bad() True when a read (or write) error occurs. clear( ) Clears all bad bits and restores good( ) condition. close( ) Flush all buffers and close file stream.
22
11 7/24/2018
When checking to see if a file opened, clear bad bits between tries while( true ) { cerr << “Please enter file name : “; cin >> filename; infile.open( filename.c_str( ) ); if( infile.good( ) ) break; infile.clear( ); }
23
Likewise When Checking Keyboard Input while( true ) { cerr << “Please enter your age: “; cin >> age; if( cin.good( ) && age > 0 && age < 120 ) break; cin.clear( ); cerr << “Invalid input, please try again.\n”; }
24
12 7/24/2018
Review
Given the following code, which correctly writes "apples" to file outfile.txt?
ofstream outFS; outFS.open("outfile.txt");
A. outfile.txt << “apples”; B. outFS << “apples”; C. outfile.txt >> “apples”; D. outFS >> “apples”; E. ofstream << “apples”;
25
Three ways to know how much data to read from a file:
1. Using a counter, usually read from the file, but it could come from other sources. 2. Using a sentinel value, indicating the end of valid data. Requires that there exist some ( combination of ) value(s) that are not valid. 3. Detecting the end of the file. • So suppose you wanted to read triplets of ( x, y, z ) doubles from a file . . .
26
13 7/24/2018
Reading data from a file using a data counter infile >> nData; // Two checks for( int i = 0; i < nData; i++ ) { infile >> x >> y >> z;
// Check, then use 4 } 3.14 27.5 42.0 109.9 -15 6.02e23 1.0 2.0 3.4 0.0 15.8 17.323
27
Reading data from a file using a sentinel value int nData = 0; while( true ) { infile >> x >> y >> z; // Check this worked if( x == 0.0 && y == 0.0 && z == 0.0 )
break; 3.14 27.5 42.0 nData++ 109.9 -15 6.02e23 1.0 2.0 3.4 // use data 0.0 15.8 17.323 } 0.0 0.0 0.0
28
14 7/24/2018
Detecting the end of file
• The eof( ) method of the stream class will return true when an error has occurred trying to read past the end of the file. • Reading the last valid byte of data in the file ( successfully ) does not trigger eof() to true. • End of file can be detected by checking eof( ), or alternatively by checking good( ). The latter also detects other problems, such as data types.
29
Always check for valid data BEFORE using it !
WRONG RIGHT while( infile.good( ) ) { while( true ) { infile >> x >> y; infile >> x >> y; // use x, y if( !infile.good( ) ) break; } // use x, y The last time through the loop, >> fails, } and x and y retain their previous values.
30
15 7/24/2018
A few good things to know
• while( “condition” ) expects “condition” to be of type boolean, or convertable to boolean. • The “result” of the >> operator is the stream that was read from. • Streams include a conversion to boolean: – If the status of the stream is good, then the conversion yields “true”. – Otherwise it yields “false”
31
(Clever/Tricky) Reading data from a file by detecting the end of the file while( infile >> x >> y >> z ) { use x, y, z safely in loop } 3.14 27.5 42.0 109.9 -15 6.02e23 • The code will try to read. 1.0 2.0 3.4 • The “condition” is the 0.0 15.8 17.323 resulting stream state. • The state is “true” only if the read attempt was successful.
32
16 7/24/2018
getline( )
• When reading data into a string with >>, it will only read up to the next whitespace, and will leave trailing whitespace ( newlines ) in the input stream. • The getline( istream &, string & ) function reads an entire line of text into a string variable, and discards the trailing newline. • The line can then be inspected, and later parsed into variables, ( using a stringstream. )
33
String Streams
• An istringstream is a kind of istream; An ostringstream is a kind of ostream; • Similar to file streams, string streams use strings as sources or destinations of data. I.e. one can “read” from an istringstream, and “write” out to an ostringstream. • #include
34
17 7/24/2018
Connecting a string stream to a particular string variable.
• The string variable can be specified when the string stream is created: – string line; – istringstream inStream( line ); • Or, it can be attached later, replacing any previously attached string: – istringstream inStream; – inStream.str( line );
35
Input checking using getline( ) and string streams string line; istringstream inString( line ); double x; cerr << “Please enter a value: “; getline( cin, line ); // Check characters in line for validity. If good, . . . inString >> x;
36
18 7/24/2018
Command Line Arguments
• We have been writing “int main( void );” • An alternate form is • “int main( int argc, char * argv[ ] );” – argc is a counter of the number of arguments given on the command line. ( Including the command. ) – argv is an array of C-style “arrays of chars”, i.e. C-style character strings. – argv[ i ] is a single C-style character string.
37
Command Line Arguments by example program “argtest” int main( int argc, char* argv[] ) {
// Prints argc and argv values cout << "argc: " << argc << endl; for ( int i = 0; i < argc; i++ ) { cout << "argv[" << i << "]: " << argv[i] << endl; }
return 0; }
38
19 7/24/2018
Sample results from running argtest
Note: argv[0] can be > ./argtest printed in (error) > ./argtest Hey argc: 1 messages to report ABC 99 -5 the name of the argv[0]: ./argtest program, even if argc: 5 someone renames the file. argv[0]: ./argtest > ./argtest Hello Note also that argc argv[1]: Hey includes the argc: 2 program name argv[2]: ABC stored in argv[0]. argv[0]: ./argtest argv[3]: 99 argv[1]: Hello argv[4]: -5
39
Converting text strings to numbers
• Command line arguments are C-style text strings, not integers, doubles, or C++ strings. • For example, “42” is char ‘4’ followed by ‘2’. • The function “int atoi( char [ ] );” converts a text string to an int. ( a.k.a. int atoi( char * ); ) • double atof( char * ); converts to a double. • long atol( char * ); converts to a long int. • Other similar functions also exist.
40
20