CMSC 202 Streams Warmup What happens in the following? vector<string> names; names.at(0) = “Fred”; names.at(1) = “Flintstone”; for (int i = 0; i <= names.size(); ++i) cout << names.at(i) << “ “; cout << endl; What is a stream? Flow of characters (or other data) Input Output Characters that come IN to your program Characters that come OUT of your program Input/Output (Sources/Sinks) Input: Keyboard, File, … Output: Monitor, File, … Standard In/Out Standard in Standard out cin cout Why are these interesting? Under any OS – these can be “redirect” You can treat a file as cin You can treat a file as cout Error Stream cerr Standard error stream NOT redirected when cout is redirected Use exactly like cout Example if (denominator == 0) { cerr << “Fatal error: denominator == 0” << endl; exit(1); } File I/O File streams work EXACTLY like cin/cout More setup is required Open a file Read from/Write to a file Close the file Library #include <fstream> File Input ifstream Datatype for file input Opening an input file ifstream fin(filename); Or… ifstream fin; fin.open(filename); Reading from an input file (you can read any primitive!) char a; fin >> a; Closing an input file fin.close(); File Input - Example Read a list of last names from a file ifstream fin(“names.txt”); vector<string> names; string name; What’s while (fin >> name) { names.push_back(name); } happening here? File Output ofstream Datatype for file output Opening an output file ofstream fout(filename); Or… ofstream fout; fout.open(filename); Writing a char to an output file char a = ‘A’; fout << a; Closing an output file fout.close(); File Output - Example Write a list of names to a file ofstream fout(“names.txt”); vector<string> names; string name; // Assume vector gets values… for (int i = 0; i < names.size(); ++i) { fout << names[i] << endl; } File Streams - #1 Issue Streams expect a C-string as its parameter Example string inFilename = “input.txt”; ifstream fin( inFilename.c_str() ); string outFilename = “output.txt”; ofstream fout( outFilename.c_str() ); What does c_str() do? Look back at the string material! Practice Open a file for input called “phones.txt” File has a name (string) followed by a number (int) Read in the data from the file Close the input file Open a file for output called “reverse.txt” Print the number followed by the name to the file Close the output file Input Streams – Pitfall! Mixing getline() and >> can be bad! >> Skips all leading whitespace Leaves trailing whitespace for next extraction Leaves the \n character getline Retrieves until end of line character Removes the \n character, but does not store it Input Streams – Pitfall! Example int age; string name; cout << "Input your age and first name"; cin >> age; getline( cin, name ); User types 42 Bob Smith age == 42 name == “” Solution? cin.ignore(); cin.ignore(1000, ‘\n’); // discard a single character // discard up to 1000 chars, stopping at \n Checking for end-of-file End of file (fin) or End of input (cin) 3 strategies while (!fin.eof()) while (fin >> variable) while (fin) // Best // Pretty good // NOT preferred… .eof() Returns “true” if EOF character has been seen Formatting Output Setf – set formatting flags outStream.setf( ios::fixed) outStream.setf( ios::showpoint) Output is right-justified in output field outStream.setf( ios::left) Floating point values have trailing zeros outStream.setf( ios::right) Floating point values have a decimal point Output is left-justified in output field Setf stays in effect until reset Formatting Output outStream.precision( int places ) Sets the number of places to the right of the decimal Stays in effect until next call to precision() outStream.width( int size ) Sets minimum number of spaces to use to output the NEXT item Only works on ONE item at a time… HINT: great for aligning tabular output! Manipulators Library setprecision( int places ) Same as outStream.width( int size ) outStream << setw(10) << Name << endl; fixed Same as outStream.precision( int places ) outStream << setprecision(2) << money << endl; setw( int size ) #include <iomanip> Same as setf( ios::fixed ); outStream << fixed << money << endl; showpoint Same as setf( ios::showpoint ); outStream << showpoint << money << endl; Formatting Output – Pitfall! Recall Most manipulators stay “on” until reset Issue? Function that modifies these stream flags… Solution? Save the current state int savePrecision = outStream.precision(); int saveFlags = outStream.flags(); Reset the current state outStream.precision( savePrecision ); outStream.flags( saveFlags ); String Streams ostringstream Format messages and treat like a string Example string FormatMessage( int age ) { ostringstream msg; msg << "\nThis is my message\n"; msg << "John is " << setw(6) << age << " years old\n"; // use the str() function to access the // C++-string in the msg return msg.str( ); } String Streams istringstream Parse messages based on whitespace Example void PrintWords( string stringToPrint) { // create and initialize the istringstream // from the string istringstream inStream( stringToPrint ); string word; while ( inStream >> word ) cout << word << endl; } Practice Use setf, setw, fixed, showpoint, and setprecision to do the following: Ask the user for 2 names and salaries Print them formatted like this: Name --------John Doe Jane Donner Salary -----------$ 43523.00 $ 3129.97 Challenge Use vectors, files and strings to Part 1: Read in an unknown number of paired values from a file (Name - string, Phone Number - integer) Part 2: Print the collection to another file Align the output vertically Format the phone number using dashes HINT: think about using modulus % and integer division!