Introduction to Computer Science COMP 51 – Fall 2012 – Section 2 File I/O
Business Homework 4 – pass it up Drop Day – 5pm on Monday, Oct 29 th Project 4 – Wed, Nov 7 th Exam 2 – Friday, Nov 9 th 2
File I/O 3
What is a Stream? A flow of characters Input stream - Flow into program Can come from keyboard Can come from file Output stream - Flow out of program Can go to screen Can go to file 4
Streams Usage We’ve used streams already cin Input stream object connected to keyboard cout Output stream object connected to screen Streams can also connect to files on disk! 5
File Basics For this class: text files only Reading from file Program takes input data from file Writing to file Program sends output data to file Files are processed from beginning to end Other methods available (i.e. random access) We’ll discuss this simple text file access here 6
File I/O Libraries To allow both file input and output in your program: #include using namespace std; Library provides two classes: ifstream – used for input ofstream – used for output 7
Declaring Streams Streams must be declared like any other variable: ifstream myInStream; ofstream myOutStream; 8
Connecting Streams Must connect each file to a stream object myInStream.open("infile.txt"); myOutStream.open("outfile.txt"); Uses member function open to open file Where is the file located? Same folder as executable (.exe file) Anywhere on the hard drive(s) Can specify complete pathname "C:\\Users\\khughes\\infile.txt" Must use \\ because \ is a special character in C++ 9
Streams Usage Once declared, use normally! (Just like cin and cout…) Example – Input Stream int oneNumber, anotherNumber; myInStream >> oneNumber >> anotherNumber; Example – Output Stream myOutStream << "oneNumber = " << oneNumber << " anotherNumber = ” << anotherNumber; 10
File Names Programs and files Files have two labels in our programs External file name (e.g. “infile.txt”) Sometimes considered “real file name” Used only once in program (the open() function) Stream name (e.g. “myInStream”) Also called “logical file name” Program uses this name for all file activity 11
Closing Files Files should be closed when program is finished getting input or sending output Disconnects stream from file Example: myInStream.close(); myOutStream.close(); Files automatically close when program ends 12
File Flush Output is often buffered Temporarily stored before written to file Written in “groups” Occasionally might need to force writing: outStream.flush(); Function flush() works for all output streams All buffered output is physically written Closing file automatically calls flush() 13
File I/O Example – Output 14 #include using namespace std; int main() { ofstream output; output.open("U:\\scores.txt"); output << "John" << " " << "T" << " " << "Smith" << " " << 90 << endl; output << "Eric" << " " << "K" << " " << "Jones" << " " << 85 << endl; output.close(); cout << "File written" << endl; return 0; } Contents of File John T Smith 90 Eric K Jones 85
Appending to a File Standard open operation (for writing) begins with empty file Even if file exists, contents are erased! Open for append: ofstream outStream; outStream.open("important.txt", ios::app); If file doesn’t exist, it is created If file exists, output is appended to end 2 nd argument is a constant for “input output stream” (ios) 15
Checking File Open Success File opens could fail for many reasons – ideas? Input – Input file doesn’t exist Input – No permission to read file Output – No write permissions to output file Output – No space left on disk Other unexpected errors Member function fail() Place call to fail() to check stream operation success inStream.open("stuff.txt"); if (inStream.fail()) { cout << "File open failed.\n"; exit(1); } 16
End of File Check – Using eof() Use loop to process file until end Typical approach Two ways to test for end of file Member function eof() myInStream >> next; while (!myInStream.eof()) { cout > next; } Reads each character until file ends eof() member function returns Boolean 17
End of File Check – Using Read Second method read operation returns Boolean value! (myInStream >> next) Expression returns true if read successful Returns false if attempt to read beyond end of file Example: double next, sum = 0; while (myInStream >> next) { sum = sum + next; } cout << "the sum is ” << sum << endl; 18
File I/O Example – Input 19 #include using namespace std; int main() { ifstream input; string nameFirst, nameMiddle, nameLast; int score; // Open file input.open("U:\\scores.txt"); // Read file until end while(!input.eof()) { input >> nameFirst >> nameMiddle >> nameLast >> score; cout << nameFirst << " " << nameMiddle << " " << nameLast << " " << score << endl; } input.close(); return 0; } Console Output John T Smith 90 Eric K Jones 85
File Names as Input Stream open operation Argument to open() is C-string type Can be literal (used so far) or variable char filename[16]; ifstream inStream; cout > filename; inStream.open(filename); Provides more flexibility – Your program doesn’t have to be hardwired to a single file name 20
File Names as Input Can also work with C++ strings, but you need to convert it to an null- terminated C-string first 21 string filename; ifstream myInStream; cout << "Enter file name: "; cin >> filename; cout << "Now opening file " << filename << endl; myInStream.open(filename.c_str());
Input Example Read in a text file containing the names of all US states and territories in alphabetical order One per line Print each state on console One per line 22 Contents of Input File Alabama Alaska Arizona...
23 #include using namespace std; int main() { ifstream input; input.open("states.txt"); if (input.fail()) { cout << "Unable to open input file" << endl; return -1; } char state[32]; while(!input.eof()) { input >> state; cout << state << endl; } input.close(); return 0; } Initial Solution
Initial Solution Output Montana Nebraska Nevada New Hampshire New Jersey New Mexico New York North Carolina North Dakota Ohio... This is a familiar problem…
getline Example Read in a text file containing the names of all US states and territories in alphabetical order One per line How do we handle states like this? New Hampshire New Jersey New Mexico New York North Carolina North Dakota 25
26 #include using namespace std; int main() { ifstream input; input.open("states.txt"); if (input.fail()) { cout << "Unable to open input file" << endl; return -1; } char state[32]; while(!input.eof()) { input.getline(state, 32, '\n'); cout << state << endl; } input.close(); return 0; } Revised Solution What is happening? getline() will read from the stream “input” and save results to the array “state” until it sees the newline (\n) character, which is discarded. It will read up to 31 characters. The C-string will be null-terminated.
27 #include using namespace std; int main() { ifstream input; input.open("states.txt"); if (input.fail()) { cout << "Unable to open input file" << endl; return -1; } string state; while(!input.eof()) { getline(input, state, '\n'); cout << state << endl; } input.close(); return 0; } Revised Solution using C++ strings What is happening? getline() will read from the stream “input” and save results to the string “state” until it sees the newline (\n) character, which is discarded.
Revised Solution Output Properly handles multi-word state names getline is flexible – the delimiter can be any character! Newline: \n Tab: \t Any symbol you want: Implication: getline can capture multiple lines if the delimiter is NOT the newline character Montana Nebraska Nevada New Hampshire New Jersey New Mexico New York North Carolina North Dakota Ohio...
>> and getline If you use both >> and getline on the same input stream, they may get “out of sync” on delimiters On Lab 6, using cin >> letter followed by getline(array,16) would result in a null C- string being read immediately for the array This is because >> stops reading at the newline To handle this, use cin.ignore(100,’\n’) to flush the remaining input 29
Project 4 – Hangman 30 Project goals – Gain experience with: File I/O Strings of characters Arrays of characters Arrays of other data types Hang ‘Em High, © United Artists, 1968
Hangman The goal of the game is to guess a word letter by letter before you run out guesses (and body parts) Your program needs to Randomly pick a string of characters from a file Track which letters have been guessed Find all letters that match a guess Recognize when a letter is and is not matched Update the display 31
Program Operation Read the entire file once to determine how many lines there are Tip: Use getline() Pick a capital at random from the file Display the gallows and the word Substitute an underscore ‘_’ for each letter Tip: for strings, use the.size() function to get the size of the string (i.e., int size = myString.size(); ) Prompt the user for a letter Determine how many characters in the capital match the letter If any, need to display them from now on If none, the user gets a miss 32
ASCII Characters 33
ASCII Character Arithmetic You can do simple arithmetic to change an ASCII character by adjusting its “number” You might not need it for this project, but it’s a good thing to know. 34 char letter = 'A'; letter = letter + 3; cout << letter; // output is ‘D’
Program Operation Questions you need to answer for yourself How do you know which letters to display, and which to not display? How do you decide which body parts need to be displayed? How do you keep track of which letters the user has used? How do you tell when the user has won? And how do you test your solutions to these questions? 35
Testcase Development Why are we requiring test cases? Common scenario: “Sam” writes 1000 lines of code, compiles and runs it, and finds out the program doesn’t work right Where should Sam start looking for the error? Should never have gone this far without testing! Many people tried to add test cases after writing and testing the full program This is totally pointless! Also, a test case isn’t just making a copy of the function and renaming it 36
Testcase Development Write your twin functions as you are developing the rest of the program As you write the function, think about how you can test what it does 37
Questions? ? ? ? 38