530 likes | 626 Views
19-Jul-2006. Today’s Objectives. Announcements Homework #5 is due next Monday, July 24. Since this date is so close to the end of the semester, no late assignments will be accepted and email will NOT be accepted! Quiz #4 File Processing (Ch. 17) Files and streams Reading from files
E N D
19-Jul-2006 Today’s Objectives • Announcements • Homework #5 is due next Monday, July 24. Since this date is so close to the end of the semester, no late assignments will be accepted and email will NOT be accepted! • Quiz #4 • File Processing (Ch. 17) • Files and streams • Reading from files • Writing to files • Adding structure to files • Using seekg, seekp, tellg, and tellp • Data Structures (Ch. 21) • Self-referential structures and classes • Linked lists
Quiz #4 Closed book 20 minutes Please clear your desks andlog off from the computer
File Processing Chapter 17
File Processing (Deitel, 844) Files and Streams • File • Used to store data • Storing data in a file makes the data “persistent” • File = a sequence of bytes • Stream = a sequence of bytes • When a file is opened, a stream object is associated with the file • The stream object connects the file with your program
File Processing (Deitel, 845) File Stream Classes and Header • <fstream> • ifstream • Used for input from a file • From the template class basic_ifstream<> • ofstream • Used for output from a file • From the template class basic_ofstream<> • fstream • Used for both output and input with a file • From the template class basic_fstream<>
Filename as a C-style string Name of the stream object Name of the class that is used for input from a file File Processing (Deitel, 847) Reading from a File char *filename = "movies.dat"; ifstream inFile( filename ); //open for reading
It’s a good idea to check whether the file was opened successfully! • Use operator! to check the state of the stream object • Checks the failbit File Processing (Deitel, 847) Reading from a File char *filename = "movies.dat"; ifstream inFile( filename ); //open for reading if( !inFile ) { cerr << "Unable to open " << filename << endl; }
A stream’s eof() function returns true if the end of the stream has been reached. File Processing (Deitel, 847) Reading from a File char *filename = "movies.dat"; ifstream inFile( filename ); //open for reading if( !inFile ) { cerr << "Unable to open " << filename << endl; } else { while( !inFile.eof() ) { Movie tempMovie; inFile >> tempMovie; //reading from the file store.addRentalItem(tempMovie); }
File Processing (Deitel, 847) Reading from a File char *filename = "movies.dat"; ifstream inFile( filename ); //open for reading if( !inFile ) { cerr << "Unable to open " << filename << endl; } else { while( !inFile.eof() ) { Movie tempMovie; inFile >> tempMovie; //reading from the file store.addRentalItem(tempMovie); } inFile.close(); } What would be likely to happen if we did not explicitly close the file? Hint: “infile” is an object.
Filename as a C-style string Name of the stream object Name of the class that is used for output to a file File Processing (Deitel, 847) Writing to a File char *filename = "customers.dat"; ofstream outFile( filename ); //open for writing
Check whether the file was opened successfully! File Processing (Deitel, 847) Writing to a File char *filename = "customers.dat"; ofstream outFile( filename ); //open for writing if( !outFile ) { cerr << "Unable to open " << filename << endl; }
File Processing (Deitel, 847) Writing to a File char *filename = "customers.dat"; ofstream outFile( filename ); //open for writing if( !outFile ) { cerr << "Unable to open " << filename << endl; } else { for( int i=0; i<sz; ++i ){ outFile << myData[i].getID() << '\n'; outFile << myData[i].getFirstName() << '\n'; outFile << myData[i].getLastName(); if( i < sz - 1 ) outFile << '\n'; } Write the data to the file.
File Processing (Deitel, 847) Writing to a File char *filename = "customers.dat"; ofstream outFile( filename ); //open for writing if( !outFile ) { cerr << "Unable to open " << filename << endl; } else { for( int i=0; i<sz; ++i ){ outFile << myData[i].getID() << '\n'; outFile << myData[i].getFirstName() << '\n'; outFile << myData[i].getLastName(); if( i < sz - 1 ) outFile << '\n'; } outFile.close(); }
File Processing (Deitel, 848; Lippman, 1097) Opening Files • A stream object can be created without opening a file ofstream outFile; • Then it can be opened later outFile.open("customers.dat"); • If a file is opened for output and it does not already exist, a new file will be created automatically
File Processing (Deitel, 847; Lippman, 1097) Appending to a File • By default, when an ofstream object is opened for output, all data already stored in the file is discarded • To keep the data that is in the file and add more data to the end, open the file in append mode ofstream outFile( "customers.dat", ios::app ); Specifies the file open mode, see Fig. 17.5, page 847. ios::app specifies append mode ios::out specifies output mode, discard the content
File Processing (Deitel, 847; Lippman, 1102) Using Objects of fstream • fstream is used for both input from a file and output to a file • Use the mode argument to specify whether input, output, or both fstream io("customers.dat", ios::in|ios::app ); Specify more than one mode by using the bitwise OR operator
File Processing (Deitel, 844; Folk, 119) Unstructured Streams • If we write data to a file as an unstructured byte stream, we may not be able to retrieve it easily • Example • If we have an array of Customer objects and we write them to a file like this: for( int i=0; i<sz; ++i ){ outFile << myData[i].getID(); outFile << myData[i].getFirstName(); outFile << myData[i].getLastName(); } • Then the bytes will be written as an unstructured byte stream, and we will not be able to separate the data when the file is read 1001AlanTuring1002CharlesBabbage
File Processing (Deitel, 843; Folk, 120–125) Fields and Records • When working with files, the data is said to be composed of fundamental units called “fields” and “records” • Field = the smallest unit of meaningful data • Examples: “firstName” and “lastName” • Record = the set of fields that belong together • Example: each Customer object is a record that contains several fields
File Processing (Deitel, 843; Folk, 120–125) Adding Structure to Files • If the data is structured inside the file (i.e., the fields and records are separated), then the data can be retrieved or changed easily • There are many ways to add structure to a file • Common methods to keep fields separated • Use fields that have a set length 1001 Alan Turing 1002 CharlesBabbage • Place a delimiter at the end of each field 1001 Alan Turing 1002 Charles Babbage
File Processing (Deitel, 843; Folk, 120–126) Structured Records • Record = the set of fields that belong together • Usually, a record is equivalent to the data for one object • Common methods to keep records separated • Use records that have a set length 1001 Alan Turing 1002 CharlesBabbage • Make records a set number of fields 1001 Alan Turing 1002 Charles Babbage
File Processing (Deitel, 843; Folk, 120–126) Retrieving Data • When a file is structured, we can retrieve its data easily • Sequentially • Read data from the beginning to the end, inserting it into variables or objects • Randomly • Go directly to a specific record and read it • seekg
File Processing (Deitel, 843; Folk, 120–126) Retrieving Data Sequentially Example file structure: • Fields are separated by ‘\n’ • Each record has three lines 1001 Turing Alan 1002 Babbage Charles string ID, lName, fName; ifstream inFile( "customers.dat" ); if( !inFile ) cerr << "Unable to open file." << endl; else { while( !inFile.eof() ) { inFile >> ID; inFile >> lName; inFile >> fName; Customer tempCustomer( ID, lName, fName ); store.addCustomer(tempCustomer); } inFile.close(); }
File Processing (Deitel, 843; Folk, 120–126) Retrieving Data Sequentially Example file structure: • Fields are separated by ‘\n’ • Each record has three lines 1001 Turing Alan 1002 Babbage Charles string ID, lName, fName; ifstream inFile( "customers.dat" ); if( !inFile ) cerr << "Unable to open file." << endl; else { while( !inFile.eof() ) { inFile >> ID; inFile >> lName; inFile >> fName; Customer tempCustomer( ID, lName, fName ); store.addCustomer(tempCustomer); } inFile.close(); }
File Processing (Deitel, 851; Lippman, 1102) Using seekg seekg() • Member function of the istream class • First argument is the number of the byte in the file that the next input will get • Second argument is optional, and it is the direction for positioning, default is the beginning of the stream – ios::beg, ios::cur, ios::end • Example string temp; ifstream inFile("customers.dat"); inFile.seekg(10); inFile >> temp; //string beginning at byte 10
File Processing (Deitel, 851–826) Retrieving Data Randomly Example file structure: • Fields separated by whitespace • Each record has 23 bytes 1001 Turing Alan 1002 Babbage Charles 1003 Lovelace Ada const int RECORDSIZE = 23; long recordNumber = 0; string ID, lName, fName; ifstream inFile( "customers.dat" ); if( !inFile ) cerr << "Unable to open file." << endl; else{ cout << "Enter the number of a record: "; cin >> recordNumber; while( recordNumber > -1 && recordNumber < 2 ){ inFile.seekg( recordNumber * RECORDSIZE, ios::beg ); inFile >> ID >> lName >> fName; Customer tempCustomer( ID, lName, fName ); cout << "The customer is: " << tempCustomer << endl; cout << "Enter the number of a record: "; cin >> recordNumber; } inFile.close(); }
File Processing (Deitel, 851; Lippman, 1102) Using seekp seekp() • Member function of the ostream class • First argument is the number of the byte in the file where the next output will start • Second argument is optional, and it is the direction for positioning, default is the beginning of the stream – ios::beg, ios::cur, ios::end • Example const int RECORDSIZE = 23; ofstream outFile("customers.dat"); outFile.seekp( n * RECORDSIZE ); outFile.write("1005 ",5);//changes the ID
File Processing (Deitel, 851; Lippman, 1102) Using tellg, tellp tellg() • Member function of the istream class • Returns the current byte in the input file • Example long pos = inFile.tellg(); tellp() • Member function of the ostream class • Returns the current byte in the output file • Used to mark a position in the file so that the program can return to it later inFile.seekg( pos );
Data Structures Chapter 21
Data Structures (Goodrich, 108) Data Structure “ A systematic way of organizing and accessing data” in a computer’s memory • Simple data structures – an array, a vector, a struct, a class • More complex data structures often use self-referential structures or classes
Data Structures (Deitel, 1000) Self-Referential Struct • Contains a data field that holds a data value • Contains one or more data fields that hold a pointer to another struct object of the same type struct Node { char element; Node *next; };
Data Structures (Deitel, 1000) Struct with a Constructor • In C++, a struct can have a constructor struct Node { char element; Node *next; Node(char e=' ',Node *p=NULL):element(e),next(p){} };
Data Structures (Deitel, 1000) Self-Referential Class • Contains a data field that holds a data value • Contains one or more data fields that hold a pointer to another object of the same type class CNode { public: CNode(char e=' ',CNode *p=NULL):element(e),next(p){} void setElement( char c ){ element = c; } char getElement(){ return element; } void setNext( CNode *p ){ next = p; } CNode *getNext(){ return next; } private: char element; CNode *next; };
Data Structures (Deitel, 1000) Building a Data Structure with Self-Referential Objects Self-referential objects can be linked together to hold a collection of related data • Similar to an array • Linked list – a type of data structure built from self-referential objects Collection of objects Linked List Each object has a pointer that points to the next object
Similarities Both store data in memory Both store data in a sequence Differences Array is one block of contiguous memory List is a collection of scattered memory cells Data Structures (Deitel, 1000) Similarities and Differences Between Arrays and Linked Lists Array Linked List
struct Node { char element; Node *next; }; struct Node { char element; Node *next; }; struct Node { char element; Node *next; }; *next; *next; *next; Data Structures (Deitel, 1000) Linked List Example • We normally use a pointer to keep track of the location of the first node, called the “head node” • Each subsequent node in the list is accessed by the pointer member inside the previous node • We often use another pointer to keep track of the last node, called the “tail” • The pointer in the last node is set to NULL pHead pTail NULL
Arrays Advantages Simple Fast performance Drawbacks Size is fixed – we use up the space even if we don’t need it Size must be determined in advance Linked Lists Advantages No fixed size – use only space we need We can add more nodes at any time Drawbacks Additional time for allocating memory during program execution More complicated code Data Structures (Deitel, 1000) Arrays vs. Linked Lists
Data Structures (Deitel, 1000) Using a Linked List • If we create a class for our linked list, then we can encapsulate all of the list’s data and the operations that we can do with the list • Operations (member functions) • size • push_front • pop_front • printList • Data members • size • A pointer to the head node
Data Structures (Deitel, 1000) Starting a List Class class List{ private: struct Node { char element; Node *next; Node(char e=' ',Node *p=NULL):element(e),next(p){} }; public: List(); int size(); void push_front( char e ); void pop_front(); void printList(); private: int sz; Node *pHead; };
Data Structures (Deitel, 1000) Defining Some Member Functions List::List(){ sz = 0; pHead = NULL; } int List::size(){ return sz; }
f next g next h next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing push_front pHead NULL
next f next g next h next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing push_front pHead NULL e pHead 1. //Create a new node //Put the data into its data element //Put the address in pHead into its “next” pointer
g next next h next g next f next e next h next f next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing push_front pHead NULL e pHead 1. pHead 2. NULL //Make pHead point to the new node
e next next g next f next e next h next g next f next g next h next f next h next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing push_front pHead NULL e pHead 1. pHead 2. NULL pHead 3. NULL
//Make pHead point to the new node //Increase the size pHead = v; sz++; Data Structures (Deitel, 1000, Goodrich, 177) Coding push_front //Create a new node //Put the data into its data element //Put the address in pHead into its “next” pointer Node *v = new Node( 'e', pHead );
f next g next h next next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing printList • We use a temporary node to print the elements stored in a linked list pHead NULL current //Start at the head and print its element
f next g next h next next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing printList • We use a temporary node to print the elements stored in a linked list pHead NULL current //Start at the head and print its element //Then get the next node and print its element
f next g next h next next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing printList • We use a temporary node to print the elements stored in a linked list pHead NULL current //Start at the head and print its element //Then get the next node and print its element
f next g next h next next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing printList • We use a temporary node to print the elements stored in a linked list pHead NULL current //Start at the head and print its element //Then get the next node and print its element //Stop when it’s NULL
Start at the head Stop if it’s NULL Print the element Get the next node Data Structures (Deitel, 1000, Goodrich, 177) Coding printList void List::printList(){ Node *current = pHead; while( current ){ cout << current->element << " "; current = current->next; } }
h next g next f next e next e next f next g next h next Data Structures (Deitel, 1000, Goodrich, 177) Visualizing pop_front //Save the address of the current head as “old head” //Make the head pointer point to node #2 //Delete the old head oldHead = pHead 1. NULL oldHead pHead 2. NULL