1 / 67

File Handling in C++

File Handling in C++. Why do we need Files?. All the programs we have looked at so far use input only from the keyboard, and output only to the screen Data that is held in variables is temporary and is lost when the program execution is finished

Download Presentation

File Handling in C++

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. File Handling in C++

  2. Why do we need Files? • All the programs we have looked at so far use input only from the keyboard, and output only to the screen • Data that is held in variables is temporary and is lost when the program execution is finished • In order to store data permanently, we need to store it in files on the hard disk • The easiest way to think about a file is as a linear sequence of characters ‘W’ ‘h’ ‘y’ ‘ ’ ‘d’ ‘o’ …. CPS235: FilesAndStreams

  3. The Data Hierarchy CPS235: FilesAndStreams

  4. C++ Streams • Stream • A transfer of information in the form of a sequence of bytes • I/O Operations • Input stream: A stream that flows from an input device to the main memory ( from: keyboard, disk drive, scanner or network connection) • Output stream: A stream that flows from the main memory to an output device ( to: screen, printer, disk drive or network connection)‏ CPS235: FilesAndStreams

  5. Program Output Stream (ostream) Input Stream (istream) I/O Devices CPS235: FilesAndStreams

  6. Program Output Stream (ofstream) Input Stream (ifstream) File on Disk CPS235: FilesAndStreams

  7. Headers required for stream processing • <iostream.h> (cout, cin, cerr, clog) • <fstream.h> • class ifstream - input from file • class ofstream – output to file • class fstream - either input or output from/to file CPS235: FilesAndStreams

  8. Creating Streams • Before we can use an input or output stream in a program, we must "create" it //create an input stream ifstream in_stream; //create an output stream ofstream out_stream; CPS235: FilesAndStreams

  9. Connecting Streams to Files • Having created a stream, we can connect it to a file using the member function"open(...)” • in_stream.open(“file.txt"); • out_stream.open(“file.txt"); • it also deletes the previous contents of the file CPS235: FilesAndStreams

  10. Creating and connecting streams to files in one statement ifstream in_stream(“file.txt”); ofstream out_stream(“file.txt”); CPS235: FilesAndStreams

  11. Disconnecting Streams from Files • To disconnect a stream from a file, we can use the member function “close(...)” • in_stream.close(); • out_stream.close(); • Adds an "end-of-file" marker at the end of the file, so if no data has been output to “file.txt” since "out_stream" was connected to it, we have this situation CPS235: FilesAndStreams

  12. Checking for Failure with File Commands void main() { ifstream in_stream; in_stream.open("Lecture.txt"); if (in_stream.fail()) // or if(!in_stream) { cout << "Sorry, the file couldn't be opened!\n"; exit(1); } //.... } CPS235: FilesAndStreams

  13. Character Input Input using get() • we can extract or read single characters from the file using the member function "get(...)“ • in_stream.get(ch); has two effects: • the variable "ch" is assigned the value "'4'", and • the ifstream "in_stream" is re- positioned so as to be ready to input the next character in the file. • Diagramatically, the new situation is: CPS235: FilesAndStreams

  14. Character Output Output using put() • We can write single characters to a file opened via an ofstream using the member function "put(...)“ • out_stream.put('4'); changes the state to: CPS235: FilesAndStreams

  15. Checking for the end of an input file • The eof() function returns true if the end-of-file is reached • This function can be used in a loop to determine how many times the get() function should be called to read the complete input file CPS235: FilesAndStreams

  16. Example • Write code to copy the contents (character by character) of a file “old.txt” simultaneously to the screen and to another file “new.txt” CPS235: FilesAndStreams

  17. #include <iostream> #include <fstream> #include <conio> #include <stdlib> void main() { char character; ifstream in_stream; //create input stream ofstream out_stream; //create output stream in_stream.open("old.txt"); //connect to file if(!in_stream) //if file opening fails { cerr<<"file could not be opened"; exit(1); } out_stream.open("new.txt"); //connect to file in_stream.get(character); //read 1 char from file while (!in_stream.eof()) //loop till eof { cout << character; //display to screen out_stream.put(character); //write to file in_stream.get(character); //read next char } out_stream.close(); //disconnect stream in_stream.close(); //disconnect stream } CPS235: FilesAndStreams

  18. Input and output using >> and << void main() { char character; int number = 51; int count = 0; ofstream out_stream; ifstream in_stream1; ifstream in_stream2; /* Create the file */ out_stream.open("Integers.txt"); for (count = 1 ; count <= 5 ; count++) out_stream << number++ << ' '; out_stream.close(); CPS235: FilesAndStreams

  19. Input and output using >> and << /* Count the integers in the file */ in_stream1.open("Integers.txt"); count = 0; in_stream1 >> number; while (!in_stream1.eof()) { count++; in_stream1 >> number; } in_stream1.close(); cout << "There are " << count << " integers in the file,\n"; CPS235: FilesAndStreams

  20. Input and output using >> and << /* Count the non-blank characters */ in_stream2.open("Integers.txt"); count = 0; in_stream2 >> character; while (!in_stream2.eof()) { count++; in_stream2 >> character; } in_stream2.close(); cout << "represented using " << count << " characters.\n"; } CPS235: FilesAndStreams

  21. Input and output using >> and << Another Example void main() { ofstream outClientFile( "clients.dat", ios::out ); if ( !outClientFile ) { cerr << "File could not be opened”; exit(1); } cout << "Enter the account, name, and balance.\n” << "Enter end-of-file to end input.\n? "; //contd on next slide… CPS235: FilesAndStreams

  22. Input and output using >> and << //…contd from previous slide int account; char name[ 30 ]; float balance; while ( cin >> account >> name >> balance ) { outClientFile << account << ' ' << name << ' ' << balance << '\n'; cout << "? "; } getch(); } CPS235: FilesAndStreams

  23. File open modes • ios:: app - (append) write all output to the end of file • ios:: ate - data can be written anywhere in the file • ios:: binary - read/write data in binary format • ios:: in - (input) open a file for input • ios::out - (output) open a file for output • ios:: trunc -(truncate) discard the files’ contents if it exists • ios::nocreate - if the file does NOT exist, the open operation fails • ios::noreplace - if the file exists, the open operation fails CPS235: FilesAndStreams

  24. File open modes (defaults) • class default mode parameter • ofstream ios::out • ifstream ios::in CPS235: FilesAndStreams

  25. fstream class • An object of fstream opens a file for reading and writing simultaneously, so we can write something like fstream outClientFile; int account; char name[20]; float balance; outClientFile.open( "clients.dat",ios::out | ios::in ); //specifying multiple modes outClientFile>>account>>name>>balance; cout<<account<<" "<<name<<" "<<balance; outClientFile<<“writing something new!"; CPS235: FilesAndStreams

  26. Reading and printing a sequential file #include <iostream.h> #include <fstream.h> #include <iomanip.h> #include <stdlib.h> void outputLine( int, const char *, double ); int main() { // ifstream constructor opens the file ifstream inClientFile (“Z:\\MyFolder\\clients.dat", ios::in ); if ( !inClientFile ) { cerr << "File could not be opened\n"; exit( 1 ); } CPS235: FilesAndStreams

  27. int account; char name[ 30 ]; double balance; cout << setiosflags( ios::left ) << setw(10) << "Account“ << setw( 13 ) << "Name" << "Balance\n"; while ( inClientFile >> account >> name >> balance ) outputLine( account, name, balance ); return 0; // ifstream destructor closes the file } void outputLine( int acct, const char *name, double bal ) { cout << setiosflags( ios::left )<< setw(10) << acct << setw( 13 ) << name << setw( 7 ) << setprecision( 2 ) << resetiosflags( ios::left )<< setiosflags( ios::fixed | ios::showpoint )<< bal << '\n‘;} CPS235: FilesAndStreams

  28. Exercise • Design and implement a program that computes the average of a sequence of numbers stored in a file CPS235: FilesAndStreams

  29. Algorithm 0. Prompt for input file name 1. Read name of input file from cin into inFileName 2. Open connection named fin to file named in inFileName 3. Initialize sum, count to zero. 4. Read a value from fin into number 5. Loop: b. If no values left, terminate repetition. c. Add number to sum. d. Increment count. End loop. 6. Close fin. 7. If count > 0: display sum / count. Else display error message End if CPS235: FilesAndStreams

  30. #include <iostream> // cin, cout, ... #include <fstream> // ifstream, ofstream, ... #include <string> int main() { cout << “\nTo average the numbers in an input file,enter the name of the file: “; string inFileName; cin >> inFileName; ifstream fin(inFileName.data()); // open the //connection if(!fin) { cerr<<“File could not be opened”; exit(1); } double number, sum = 0.0; // variables for int count = 0; // computing //average CPS235: FilesAndStreams

  31. fin>>number; //read number while(!fin.eof()) { sum += number; // add it to sum count++; fin >> number; // read next number } fin.close(); // close fstream if (count > 0) cout << “\nThe average of the values in “ << inFileName << “ is “ << sum/count << endl; else cout << “\n*** No values found in file “ << inFileName << endl; } CPS235: FilesAndStreams

  32. Repositioning the file-position pointer • <istream> and <ostream> classes provide member functions for repositioning the file pointer (the byte number of the next byte in the file to be read or to be written.) • These member functions are: • seekg(seek get) for istream class • seekp (seek put) for ostream class CPS235: FilesAndStreams

  33. CPS235: FilesAndStreams

  34. Examples of moving a file pointer • fileObject.seekg( 0 ); • reposition the file-position pointer to the beginning of the file (location 0) attached to fileObject • fileObject.seekg(n) • position to the nth byte of fileObject (assumes ios::beg) • fileObject.seekg( n,ios::curr ); • position n bytes forward in fileObject • fileObject.seekg( n, ios::end ); • position n bytes back from end of fileObject • fileObject.seekg( 0, ios::end ); • position at end of fileObject The same operations can be performed using ostream member function seekp CPS235: FilesAndStreams

  35. tellg()and tellp() • Member functions tellg() and tellp() are provided to return the current locations of the get and put pointers, respectively • long location = fileObject.tellg(); CPS235: FilesAndStreams

  36. Problems with Sequential Files • Data that is formatted and written to a sequential file cannot be modified easily without the risk of destroying other data in the file • If we want to modify a record of data, the new data may be longer than the old one and it could overwrite parts of the record following it • Sequential files are inappropriate for so-called “instant access” applications in which a particular record of information must be located immediately. • These applications include banking systems, point-of-sale systems, airline reservation systems, (or any data-base system) CPS235: FilesAndStreams

  37. Random Access Files • Instant access is possible with random access files • Individual records of a random access file can be accessed directly (and quickly) without searching many other records CPS235: FilesAndStreams

  38. Binary I/O • We have seen examples of formatted I/O where each number is stored as a sequence of characters but it is not always efficient • It is more efficient to use binary I/O in which numbers are stored in the form of bytes • So, in binary I/O, an int is always stored in 4 bytes whereas its text version might be 12345 which requires 5 bytes • For binary I/O • the file should be opened in the binary mode (ios::binary) • member functions read() of the ostream class and write() of the istream class will be used for reading/writing data from/to disk CPS235: FilesAndStreams

  39. Writing Bytes with ostream Member Function write() • To write an int variable num to the file, use: outFile.write( reinterpret_cast< const char * >(&num ), sizeof( num) ); OR • outFile.write((char *)&num , sizeof( num) ); • This writes the binary version of the number’s 4 bytes • Function write treats its first argument as a group of bytes by viewing the object in memory as a const char*, which is a pointer to a byte (remember that a char is one byte) • Starting from that location, function write outputs the number of bytes specified by its second argument, an integer of type size_t CPS235: FilesAndStreams

  40. reinterpret_cast • Unfortunately, most pointers that we pass to function write as the first argument are not of type const char * • To output objects of other types, we must convert the pointers to those objects to type const char * • C++ provides the reinterpret_cast operator for cases like this in which a pointer of one type must be cast to an unrelated pointer type • You can also use this cast operator to convert between pointer and integer types, and vice versa CPS235: FilesAndStreams

  41. reinterpret_cast • A reinterpret_cast is performed at compile time and does not change the value of the object to which its operand points • Instead, it requests that the compiler reinterpret the operand as the target type (specified in the angle brackets following the keyword reinterpret_cast). • Here we are using a reinterpret case to convert an int* (the type of the expression &num) to a const char* • The same conversion would have to be done in case of the read() function of the istream class CPS235: FilesAndStreams

  42. Example of a Program that Creates a Random Access File //file: clientData.h struct clientData { int accountNumber; char lastName[ 15 ]; char firstName[ 10 ]; float balance; }; CPS235: FilesAndStreams

  43. // Creating a random access file #include <iostream.h> #include <fstream.h> #include <stdlib.h> #include “clientData.h" void main() { ofstream outCredit ("credit.dat” , ios::binary); if ( !outCredit ) { cerr << "File could not be opened." exit( 1 ); } clientData blankClient = { 0, "", "", 0.0 };for ( int i = 0; i < 100; i++ )outCredit.write((const char*) &blankClient, sizeof( clientData ) );} CPS235: FilesAndStreams

  44. Writing data randomly to a random file #include <iostream.h> #include <fstream.h> #include <stdlib.h> #include "clientData.h" void main() { ofstream outCredit( "credit.dat",ios::ate|ios::binary ); if ( !outCredit ) { cerr << "File could not be opened." << endl; exit( 1 ); } CPS235: FilesAndStreams

  45. cout << "Enter account number”(1 to 100, 0 to end input)\n? "; clientData client; cin >> client.accountNumber; while ( client.accountNumber > 0 && client.accountNumber <= 100 ) {cout << "Enter lastname, firstname, balance\n? ";cin >> client.lastName >> client.firstName >> client.balance;outCredit.seekp( ( client.accountNumber - 1 ) *sizeof( clientData ) );outCredit.write((const char*) &client , sizeof( clientData ) );cout << "Enter account number\n? ";cin >> client.accountNumber; } CPS235: FilesAndStreams

  46. Reading data from a random file sequentially #include <iostream.h> #include <iomanip.h> #include <fstream.h> #include <stdlib.h> #include “clientData.h" void outputLine( ostream&, const clientData & ); void main() { ifstream inCredit( "credit.dat", ios::in ); if ( !inCredit ) { cerr << "File could not be opened." << endl; exit( 1 ); } CPS235: FilesAndStreams

  47. cout << setiosflags( ios::left ) << setw( 10 ) << "Account” << setw( 16 ) << "Last Name" << setw( 11 )<< "First Name" << resetiosflags( ios::left ) << setw( 10 ) << "Balance" << endl; clientData client; inCredit.read( (char*) &client, sizeof( clientData ) ); while ( inCredit && !inCredit.eof() ) { if ( client.accountNumber != 0 ) outputLine( cout, client ); inCredit.read( (char*) &client, sizeof( clientData ) ); } } CPS235: FilesAndStreams

  48. void outputLine( ostream &output, const clientData &c ){ output << setiosflags( ios::left ) << setw( 10 ) << c.accountNumber << setw( 16 ) << c.lastName << setw( 11 ) << c.firstName << setw( 10 ) << setprecision( 2 ) << resetiosflags( ios::left )<< setiosflags( ios::fixed | ios::showpoint ) << c.balance << '\n';} CPS235: FilesAndStreams

  49. Updating a record using random access void main() { fstream File ("credit.dat", ios::binary|ios::out|ios::in); int accNumber; cout<<"Enter the number of the account you wish to modify"; cin>>accNumber; // move file-position pointer to correct record in file inFile.seekg( ( accNumber - 1 ) * sizeof( ClientData ) ); // read the required record from file ClientData client; inFile.read( (char*)&client, sizeof( ClientData ) ); CPS235: FilesAndStreams

  50. // update record if ( client.accountNumber != 0 ) { outputLine( cout, client ); // display the record // request user to specify transaction cout << "\nEnter charge(+)or payment(-):"; double transaction; // charge or payment cin >> transaction; client.balance += transaction; outputLine( cout, client ); // display the modified record // move file-position pointer to correct record in file File.seekp( ( accNumber - 1 ) * sizeof( ClientData ) ); // write updated record over old record in file File.write( (char*) &client, sizeof( ClientData ) ); }// end if CPS235: FilesAndStreams

More Related