7/24/2018

C/++ Programming for Engineers: Streams and Arguments

John T. Bell

Department of 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 and state “using namespace std;” : • cin - Reads from standard input ( stdin, keyboard ), using the >> operator. • cout - Writes to standard output ( stdout, screen), using the << operator. • cerr - Writes to standard error ( stderr, screen), using the << operator.

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 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” . ( 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 to use these manipulators. • Most remain in effect until specifically changed. – setw( ) is the most notable exception. setw( ) only affects the next data item that is output.

9

Floating Point Manipulators

Manipulator Description Example Use fixed-point notation. fixed 12.34 From Use scientific notation. scientific 1.234e+01 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 99.00 (showpoint)

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 "****Amy" Changes to left alignment. left "Amy " From Changes back to right alignment. right “ Amy" 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 Informs the system to flush the buffer. flush From Others Exist See http://www.cplusplus.com/reference/iostream/manipulators

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 to use file streams. • Declare variables of type ifstream or ofstream • Attach file stream to a specific file either when declaring or later using open( ) : – ifstream infile( “myInputData.txt” ); – ofstream outfile; – outfile.open( “myOutputData.txt” ); • Verify the file opened before using stream.

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 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 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 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 and #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