Streams, Files, and Formatting Chapter 8 8.1 Standard Input/Output Streams Stream is a sequence of characters Working with cin and cout Streams convert internal representations to character streams >> input operator (extractor) << output operator (inserter) Streams have no fixed size 2 Reading Data >> Leading white space skipped <nwln> also skipped Until first character is located cin >> ch; Also read character plus white space as a character – get and put functions 3 CountChars.cpp // File: CountChars.cpp // Counts the number of characters and lines in // a file #include <iostream> #include <string> using namespace std; #define ENDFILE "CTRL-D" // CTRL-Z for DOS 4 CountChars.cpp int main() { const char NWLN = '\n'; // newline character char next; int charCount; int totalChars; int lineCount; lineCount = 0; totalChars = 0; 5 CountChars.cpp cout << "Enter a line or press " << ENDFILE << ": "; while (cin.get(next)) { charCount = 0; while (next != NWLN && !cin.eof()) { cout.put(next); charCount++; totalChars++; cin.get(next); } // end inner while 6 CountChars.cpp cout.put(NWLN); lineCount++; cout << "Number of characters in line " << lineCount << " is " << charCount << endl; } cout << "Enter a line or press " << ENDFILE << ": "; // end outer while cout << endl << endl << "Number of lines processed is " << lineCount << endl; 7 CountChars.cpp cout << "Total number of characters is " << totalChars << endl; return 0; } Example of a user session: Enter a line or press CTRL-D: line one. Line one. Number of characters is 9 Enter a line or press CTRL-D: line four. Line four. Number of characters is 10 Enter a line or press CTRL-D: CTRL-D Number of lines processed is 2 Total number of characters is 19 8 Stream Functions stream.open(fname): opens a file stream stream.get(ch): extracts one character from stream stream.put(ch): inserts one character into stream stream.close(): closes an opened file stream stream.eof(): return true if end of stream is reached and false otherwise stream.fail(): returns true if a precedent open has failed and false otherwise 9 8.2 External Files Batch processing – Read data from a file (not from keyboard) • data can be examined • don’t need to retype data when you rerun program – – – – Requires use of data files (save to disk) Batch can be run during off peak use allows things to be complete at start of day Helpful is to echo-print (on the screen) read data Interactive processing – Real time systems – Ok for smaller programs – Programs that complete quickly 10 Files Naming (system-dependent) – Directory name e.g. /Myfiles/ – File name e.g. Payroll.txt – Extensions: .cc .dat .out .txt How to attach files to the stream – – – – .in stream object external file name internal name open Additional functions as part of fstream class 11 Files Declare the stream to be processed need to #include <fstream> ifstream ins; // input stream ofstream outs; // output stream Need to open the files ins.open (inFileName); outs.open (outFileName); 12 Files #define associates the name of the stream with the actual file name You can directly give file names fail() function - returns true (nonzero) if file fails to open Program CopyFile.cpp demonstrates the use of the other fstream functions – get , put, close and eof 13 CopyFile.cpp // File: CopyFile.cpp // Copies file InData.txt to file OutData.txt #include <cstdlib> #include <fstream> using namespace std; // Associate stream objects with external file // names #define inFile "InData.txt" #define outFile "OutData.txt" 14 CopyFile.cpp // Functions used ... // Copies one line of text int copyLine(ifstream&, ofstream&); int main() { // Local data ... int lineCount; ifstream ins; ofstream outs; 15 CopyFile.cpp // Open input and output file, exit on any // error. ins.open(inFile); if (ins.fail ()) { cerr << "*** ERROR: Cannot open " << inFile << " for input." << endl; return EXIT_FAILURE; // failure return } // end if 16 CopyFile.cpp outs.open(outFile); if (outs.fail()) { cerr << "*** ERROR: Cannot open " << outFile << " for output." << endl; return EXIT_FAILURE; // failure return } // end if // Copy each character from inData to outData. lineCount = 0; do { 17 CopyFile.cpp if (copyLine(ins, outs) != 0) lineCount++; } while (!ins.eof()); // Display a message on the screen. cout << "Input file copied to output file." << endl; cout << lineCount << " lines copied." << endl; ins.close(); outs.close(); return 0; } // successful return 18 CopyFile.cpp // Copy one line of text from one file to another // Pre: ins is opened for input and outs for // output. // Post: Next line of ins is written to outs. // The last character processed from // ins is <nwln>; // the last character written to outs // is <nwln>. // Returns: The number of characters copied. int copyLine (ifstream& ins, ofstream& outs) { 19 CopyFile.cpp // Local data ... const char NWLN = '\n'; char nextCh; int charCount = 0; // Copy all data characters from stream ins to // stream outs. ins.get(nextCh); while ((nextCh != NWLN) && !ins.eof()) { outs.put(nextCh); charCount++; 20 CopyFile.cpp } } ins.get (nextCh); // end while // If last character read was NWLN write it // to outs. if (!ins.eof()) { outs.put(NWLN); charCount++; } return charCount; // end copyLine 21 CopyFile.cpp Program Output Input file copied to output file. 37 lines copied. 22 File Processing Newline character eof() function returns a False if file is not empty while ( ! ins.eof()) { do stuff } Could have used getline(): string line; linCount = 0; getline(ins, line); while(line.lentgh() != 0) { lineCount++; outs << line << endl; getline(ins, line); } 23 8.3 Using External File Functions Payroll Case Study Program 1: computes salary using hours and rate Input file: e.g. Adam Smith Thomas New Ayisha Martin Output file: e.g. Adam Smith Thomas New Ayisha Martin 35.5 7.25<nwln> 40.0 6.50 <nwln> 20.0 8.00 <nwln><eof> $257.38<nwln> $260.00<nwln> $160.00<nwln><eof> Program 2: (not handled here) Does further processing on output file of program 1 24 Payroll Case Structure Chart Write the payroll file Prepare files Process all employees Display payroll processEmp 25 ProcessEmp Structure Chart Process all employees Read employee first and last names Read employee salary data (hours and rate) Compute salary Add salary to total payroll Write first and last names and salary 26 Payroll.cpp // File: Payroll.cpp // Creates a company employee payroll file // computes total company payroll amount #include #include #include #include <fstream> <cstdlib> "money.h" "money.cpp" using namespace std; 27 Payroll.cpp // Associate streams with external file names #define inFile "EmpFile.txt" // employee file #define outFile "Salary.txt" // payroll file // Functions used ... // PROCESS ALL EMPLOYEES AND COMPUTE TOTAL money processEmp(istream&, ostream&); int main() { ifstream eds; ofstream pds; money totalPayroll; 28 Payroll.cpp // Prepare files. eds.open(inFile); if (eds.fail ()) { cerr << "*** ERROR: Cannot open " << inFile << " for input." << endl; return EXIT_FAILURE; // failure return } pds.open(outFile); if (pds.fail()) { 29 Payroll.cpp cerr << "***ERROR: Cannot open " << outFile << " for output." << endl; eds.close(); return EXIT_FAILURE; // failure return } // Process all employees and compute total // payroll. totalPayroll = processEmp(eds, pds); // Display result. cout << "Total payroll is " << totalPayroll << endl; 30 Payroll.cpp // Close files. eds.close(); pds.close(); return 0; } 31 Payroll.cpp // Insert processEmp here. // Process all employees and compute total // payroll amount // Pre: eds and pds are prepared for // input/output. // Post: Employee names and salaries are // written from eds to pds // and the sum of their salaries is returned. // Returns: Total company payroll money processEmp (istream& eds, ostream& pds) { 32 Payroll.cpp string firstName; string lastName; float hours; money rate; money salary; money payroll; company payroll // // // // input: hoursWorked input: hourly rate output: gross salary return value - total payroll = 0.0; // Read first employee's data record. eds >> firstName >> lastName >> hours >> rate; 33 Payroll.cpp while (!eds.eof()) { salary = hours * rate; pds << firstName << “ “ <<lastName << “ “ << salary << endl; payroll += salary; } // Read next employee's data record. eds >> firstName >> lastName >> hours >> rate; } // end while return payroll; // end processEmp 34 PayrollFile.cpp Program Output Total payroll is $677.38 35 8.4 More on Reading String Data Getline - could be used to process an entire line of data Use # as a delimiter character getline (eds, name, ‘#’); Advance the newline getline (eds, name, ‘\n’); Use care when choosing cin, get or getline 36 Getline() and Ignore() getline(istream& in, string& s) Reads a line from input stream in and stores it in s getline(istream& in, string& s, char delimiter) Reads all characters up to ‘delimiter’ and stores them in s (delimiter is read but not stored in s!) ins.ignore(int n, char delimiter) Extracts (but not store) up to n characters from input stream ins until the first ‘delimiter’ character is encountered. Delimiter is extracted but not stored 37 8.5 Input/Output Manipulators Chapter 5 covered setw width Also endl has been introduced boolalpha has been also used to get ‘true’ and ‘false’ from keyboard Can be used with the cout and << #include <iomanip> when using manipulators Can be used with external files like cin and cout 38 I/O Manipulators setw(int n): set the width of the next output setprecesion(int n): sets the precision for (float) numbers (default is 6) boolalpha: enables true/false for I/O noboolalpha: disable previous operation fixed: decimal notation of floats scientific: scientific notation of floats showpoint: display decimal point also for integers noshowpoint: undo previous operation left: left-adjust output in field right: right-adjust (default) skipws: skip white spaces on input (default) noskipws: undo previous operation 39 Formatting with State Flags Depending on the setiosflags or unsetiosflags – Output can be controlled by other format state flag – Flags are enumerated types ios::flagname Flags e.g.: – boolalpha, fixed, left, right, showpoint etc Examples: cin.setf(ios::boolalpha); cout.setf(ios::boolalpha); 40 8.6 Common Programming Errors Connecting streams and external files – Declare stream object and open the file Watch use of while loops when processing – Test values see what you actually have Reading past the eof White space Newline character Formatting via flags 41