Sie sind auf Seite 1von 8

CHAPTER SEVEN FILES AND STREAMS

File input/output So far, we saw programs taking input data from the user via the keyboard using the extraction operator >> with the object cin, and displaying output to the user via the monitor using the insertion operator << with the object cout. Treated this way, the data that is processed by your program is lost by the time the program is stopped or when the computer is turned off, because your program used the computers volatile memory (RAM). It is obvious that most useful programs need to read and write data to disk files. This part of the course deals with handling a programs data in relation with disk files. Header files Data flow in general (to and out of the program) is called stream in C++. We include the header file iostream.h for data flow to the monitor and from the keyboard using the objects cout and cin. For data streams to /from disk files, we include the header file fstream.h, in which the iostream class and other classes for disk file input /output like ofstream, ifstream and fstream are defined. (If we include fstream.h, we do not need to include iosream.h) Creating objects for file streams Earlier, we used the predefined cout and cin objects of the iostream class for stream output to video display and input from keyboard respectively. In file input /output, we create our own objects for both file output and input purposes using the following classes. ofstream: to create objects for output data to files ifstream: to create objects for input data from files fstream : to create object that can be used for both input/output data from and to files String input output Example: the following program writes strings to a file #include<fstream.h> // for ofstream void main( ) { ofstream my_ofile ("test.txt"); my_ofile<<"This is a trial text\n"; my_ofile<<"to be written in disk file \n"; my_ofile<<"by file name \"Test\".\n"; } In this program, we created an object called my_ofile using the ofsteam class, which is used to create objects for output data to files, and at the same time the file name test (to be created on the disk) is given to our output object as an argument in quotations. A file with the .txt extension will be created in the folder tc\bin, where tc.exe (the C++ compiler itself) is located in. You can set the drive for the above program as:

ofstream my_ofile ("a:test.txt"); if you want the file to be created on a floppy disk. Using the insertion operator << with our object my_ofile, the program outputs the text to the file. Note that the above program displays no output to the screen. Example the following program reads string from file. #include<fstream.h> #include<conio.h> void main ( ) { const int MAX=80; char line[MAX]; ifstream my_ifile("test.txt"); while (my_ifile) { my_ifile.getline(line,MAX); cout<<line<<endl; } getch( ); } Here, we created our object my_ifile using the ifstream class, which is used to create objects for input data from files. The name of the file to be opened from disk for reading by the program is given to the object as an argument. In this case, we did not use the extraction operator >> to read data from file and put it on the string variable line because this operator has a problem in reading embedded spaces in strings, as we saw it in earlier chapters. Instead, the getline( ) function is used; this function reads characters including embedded spaces until it encounters the \n character, and places the resulting string in the variable supplied as an argument. The maximum size of the variable is given as the second argument. In this program, the contents of the variable line are displayed to the screen after each line is read from the file test. Detecting EndOf --File An ifstream object, such as my_ifile in the above program, has a value that can be tested for various error conditions. If the error condition is true, the object (my_ifile in our case) returns a zero value; otherwise its nonzero. The while loop here is used to check the End Of File (EOF), which is a signal from the hardware when a read or write operation has reached the end of file. When EOF is reached in the above program, zero value is returned from the object and the while loop makes the control jump the reading operation. Before we go to see how to read/write data other than in string format to files, let us summarize what we did so far. To write or read strings to /from files, we simply create objects using either ofstream or ifstream classes. We can give whatever name we like to these objects like we give names to variables. Then we use << with our object to write the string from the program to the opened file, in the same way we used << with cout to display an output to the monitor.

Also to read strings from file to our program, we defined a string variable and used the getline( ) function to read the string from file to the variable. (This function is similar with the cin.get ( ) function that reads strings with embedded blanks from keyboard). As mentioned earlier, we can also use the extraction operator >> to read strings from file to variables in our programs, but as you already saw, using the function getline( ) is more advantageous in reading strings from files. Character Input Output In addition to writing and reading strings to files, we also need to do so with single characters. We use the put( ) and get( ) functions in such cases. They output and input single character at a time. Example the following program writes as string, character by character, to a file. #include<fstream.h> #include<string.h> void main ( ) { char str[]="this string will be written to a file character by character"; ofstream o_file("test2.txt"); for(int j=0;j<strlen(str);j++) o_file.put(str[j]); } In the program, we used the put( ) function in combination with our ofstream object o_file. The string is treated to be written character-by-character using the for loop to the file test2. Example The following program reads characters from a file and displays then to the monitor. #include <fstream.h> #include<conio.h> void main() { char ch; ifstream i_file ("test2.txt"); while (i_file) { i_file.get(ch); cout<<ch; } getch( ); } The while loop in this program reads characters from the opened file test2, puts the character on the variable ch, and displays it to the monitor, until the EOF is reached. We could use the statement i_file>>ch; to read characters from the file to the program, but this operator ignores the blank spaces in between the words, so it is better to use the get( ) function. Writing / Reading Structures Data To /From Files As we saw earlier in this course, structures are collections of different data types; they are not simple characters to be written to or read from files using the functions weve used before, such as <<, >>, get( ), and put( ). We use the write( ) and read( ) functions to do file read write operations on user defined data types like structures. The data stored in the structure is treated as

a sequence of bytes. This way of data handling is called binary file (unlike the previous character files in the above programs). We can create objects of the fstream class, to use same object for both reading and writing purposes to a file. (We already saw ifstream and ofstream classes). E.g. fstream my_rec; // creating an object called // my_rec for both reading and // writing data to a file.

The open( ) function In previous examples of character files, we created a file object and initialized it with a file name, i.e. the file to be created on the disk, in the same statement. e.g. ofstream my_ifile (test.txt); But in binary file operation, we usually create a disk file in one statement and open it is another, using the open( ) function , which is a member of the fstream class. : E.g. fstream my_rec; my_rec. open (file1, ios:: app| ios:: out | ios::in ); : In the open( ) function we include several mode bits to specify certain aspects of the file object we are opening. The most common mode bits for the open( ) function are: app start reading or writing at end of file (Append). in open file for reading (default for ifstream) out open file for writing (default for ofstream) In writing the structure data to a file, we use the write( ) function as mentioned earlier. e.g #include<fstream.h> #include<conio.h> #include<ctype.h> // for the function toupper( ) struct person { char name [25]; int age; }; void main ( ) { clrscr(); char ans; person pers; fstream my_rec; my_rec.open ("record1",ios::app|ios::out); do{ cout<<"Enter name: ";

cin>>pers.name; cout<<"Enter age: "; cin>>pers.age; my_rec.write ((char*)& pers, sizeof(pers)); cout<<"Add more? [Y/N]"; cin>>ans; ans=toupper(ans); } while(ans=='Y'); getch(); } The above program accept name and age of a person from a user, using the structure data type pers, and write the structure data to the disk file reord1; the program continues accepting and writing the data as much as the user wants to continue (because of the do while loop). In the program, we created an fstream object called my_rec. We wanted this object only to write data to the disk file and hence used the mode bit ios:: out. (Note that it is also possible to add the mode bit ios:: in at the same time if we wanted both to write and read using the object my_rec). We also wanted the object to write the data in the specified file (record1) at the end of the previous contents of the file, i.e. to append the data (if there is any); that is the reason for opening it in ios::app mode. This mode bit avoids over writing (deleting) the data contained in the disk file if it was already created and has data. In the program the contents of the pers structure are written to disk, each time the user enter, using the write ( ) function. This function takes two arguments: the address of the structure to be written, and the length of the structure in bytes. We use the sizeof( ) operator to find the length of the pers structure. The address of the structure must be cast to type pointer to char. For the above case, sizeof(pers) returns 27 as the length of the pers structure, if the machine youre working on assigns 1 byte for char and 2 bytes for int. We read structures from file using another but similar function, read( ). The arguments of this function are the same as that of the write( ) function. In reading data from file to a program, from which point or position of the disk file do you think the read( ) function starts reading ? It starts reading from where the file pointer is. File pointers File pointers are integer numbers that starts from 0, according to the byte number in the file where reading or writing will take place. (Do not confuse file pointers with the variable address pointers that we saw earlier; file pointers are simply numbers). There are built in functions to access the file pointer, and hence to make us be able to write to or read from a specific location in the file, as we need,

We use the seekg( ) and tellg( ) functions to take the file pointer to some position in the file or to read (get) the position of the file pointer respectively when the file is opened for reading. And we use the seekp( ) and tellp( ) functions to take the file pointer or read (get)its position like the above case when the file is opened for writing. seekg( ): sets the file pointer in the file to the position of the number of bytes given to it as an argument. As mentioned above, we use this function when reading the file. eg. object_name.seekg(0); // this makes reading to start from the beginning of the file //when the file pointer is not at the beginning (since files //start from the byte 0).

This function can also take a second argument; the first argument represents the offset from a particular location in the file, and the second specifies the location from which the offset is measured. Thus: ios::end : ios:: beg: ios::cur: * eg. end of file beginning of file current pointer position in the file. //takes the pointer 22 bytes back from // the end of file.

object_name.seekg(-22, ios::end);

tellg( ) : this function returns the current position of the file pointer when the file is opened for reading. e.g. int pos; pos = my_rec.tellg( ); // assigns the current file pointer position (in byte no) // to the variable pos. In addition to the earlier error handling mechanism we saw for EOF, we can use the function eof( ). This function returns a nonzero value when an EOF is encountered. The following program receives persons name and age, until the user wants to stop using a structure to a file. The program then displays what is available in the opened file to the monitor. Note that the program displays not only the data entered currently, but also data entered previously to the file. This is because we put the file pointer at the beginning position of the file using seekg( ). Example : opening a file both for writing and reading. #include<fstream.h> #include<conio.h> #include<ctype.h> struct person {

// for the function toupper( )

char name[25]; int age; }; void main() { clrscr(); char ans; person pers; fstream my_rec; my_rec.open ("record2",ios::app|ios::out| ios:: in ); do{ cout<<"Enter name "; cin>>pers.name; cout<<"Enter age "; cin>>pers.age; my_rec.write((char*)&pers, sizeof(pers)); cout <<"Add more? [Y/N] "; cin >> ans; ans=toupper(ans); }while (ans=='Y'); cout<<"The data in the file is :\n"; my_rec.seekg(0); my_rec.read((char*)&pers,sizeof(pers)); while(!my_rec.eof()) { cout<<"\nName :"<<pers.name<<endl; cout<<"Age :"<< pers.age <<endl; my_rec.read((char*)&pers, sizeof(pers)); } my_rec.close(); // optional getch(); } After the while loop and before closing the opened file in the above program, you can add the following piece of code to know how many persons data is in the opened file. : int pos; my_rec.seekg(0,ios::end); pos=(my_rec.tellg()/sizeof(pers)); cout<<"\nThere are "<<pos<<" people in the file"; : Remember that the function tellg( ) returns the file pointer byte number (an integer value). The following program can also read a persons information at a specific number in the file (the file created by the above program).

#include<fstream.h>

#include<conio.h> struct person { char name[25]; int age; }; void main() { clrscr(); int num,pos; person pers; ifstream my_rec("record2"); cout<<"Enter the person's number: "; cin>>num; pos=(num-1)*sizeof(pers); my_rec.seekg(pos); my_rec.read((char*)&pers, sizeof(pers)); cout<<"\nName :"<<pers.name<<endl; cout<<"Age :"<< pers.age <<endl; getch(); }

Das könnte Ihnen auch gefallen