Sei sulla pagina 1di 20

Programming Language-II

Lecture # 19

Outline
Object I/O
I/O with Multiple Objects
The Mode Bits
File Pointers: get and put
Error Handling in File I/O

Object I/O
We can also write objects, of user defined
classes, to files.
Similarly, we can read objects from files.
When writing an object we generally want to
use binary mode.
This writes the same bit configuration to disk that
was stored in memory
and ensures that numerical data contained in
objects is handled properly.
3

Example: Object I/O


#include<iostream>

cin>>name;

using namespace std;

cout<<"Enter age: ";

class Person

cin>>age;

private:

void showData()

char name[40];

int age;

cout<<name<<endl

public:

<<age<<endl;

void readData()
{
cout<<"Enter name: ";

}
};

Example: Object I/O


#include<iostream>

os.write(reinterpret_cast<cha
r*>(&p), sizeof(Person));

#include<fstream>

os.close();

#include"person.h"

#include<string>
using namespace std;

Person p1;

int main()

ifstream is("person.dat",
ios::binary);

{
Person p;
p.readData();
ofstream os("person.dat",
ios::binary);

is.read(reinterpret_cast<char*
>(&p1), sizeof(Person));
p1.showData();
return 0;
}

I/O with Multiple Objects

int main() {
char ch;
Person p;
fstream file;
file.open("group.dat",ios::app | ios::out | ios::in |
ios::binary);
do{
p.readData();
file.write(reinterpret_cast<char*>(&p), sizeof(Person));
cout<<"Enter another person(y/n)? : "<<endl;
cin>>ch;
} while(ch=='y');
Continues
Continues

I/O with Multiple Objects


file.seekg(0); //reset to start of file
file.read(reinterpret_cast<char*>(&p),
sizeof(Person));
while(!file.eof())
{
cout<<"\nPerson: ";
p.showData();
file.read(reinterpret_cast<char*>(&p),
sizeof(Person));
}
return 0;
}
7

I/O with Multiple Objects


If we want to create a file stream object that
can be used for both, reading to and writing
from a file, we need to create an object of
fstream class.
open() function is a member of the fstream
class.
We can create a stream object once, and can
open it repeatedly.
8

The Mode bits


ios::binary is one of the mode bits.
The open() function has used several mode bits in the
line
file.open("group.dat",ios::app | ios::out | ios::in |
ios::binary);

ios::app is used when we want to preserve whatever


was in the file before, i.e., whatever we write to the file
will be added following the existing contents.
ios::in and ios::out are used when we want to
perform both input and output to the file.
ios::binary is used for writing binary objects.
9

The vertical bars between the flags cause the bits to


be logically combined into a single integer.

File Pointers

10

Each file object has associated with it two integer


values called the get pointer and the put pointer.
These are also called the current get position and the
current put position, or __ if its clear which one is
meant __ simply the current position.
These values specify the byte number in the file
where writing or reading will take place.
When we want to read from and write to an arbitrary
location in the file, we need to control the file pointers.
The seekg() and tellg() functions allow us to set and
examine the get pointer.
The seekp() and tellp() functions perform these same
actions on the put pointer.

Specifying the Position


We can use the seekg() function with one or
two arguments.
The one argument seekg() takes a numeric
argument that represents an absolute position
in the file, from where the reading would start.
The start of the file is byte 0.
So the argument represents the position from
the start of the file.
11

Specifying the Offset


If we use seekg() with two arguments,
the first argument represents an offset from a
particular location in the file
and the second specifies the location from which
the offset is measured.

There are 3 possibilities for the 2nd argument:


beg is the beginning of the file
cur is the current pointer position
end is the end of the file

Example
12

seekg(-10, ios::end);

The seekg() with 2 Arguments


End

Begin

Offset from begin

End

Begin

Offset from end

Begin

13

Current position

End

Offset from current


position

Example: Specifying the Offset

14

int main() {
Person p;
ifstream file;
file.open("group.dat", ios::binary);
file.seekg(0,ios::end);
int endposition=file.tellg();
int n=endposition/sizeof(Person); //no. of persons
cout<<"Number of persons in file: "<<n<<endl;
cout<<"Enter person no. ";
cin>>n;
int position=(n-1)*sizeof(Person);
file.seekg(position); //bytes from start
file.read(reinterpret_cast<char*>(&p), sizeof(Person));
p.showData();
return 0;
}

Error Handling in File I/O


So far, we have assumed that the files we opened for
reading already existed, and that those opened for
writing could be created or appended to.
We have also assumed that there were no failures
during reading or writing.
It is important to verify such assumptions and take
appropriate action if they turn out to be incorrect.
A file that we think may not, or a filename that we
assume we can use for a new file may already apply
to an existing file.

15

Or, there may be no more room on the disk, or no disk


in the drive.

Reacting to Errors

16

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void main() {
const int MAX=100;
int buff[MAX];
int j;
for(j=0; j<MAX; j++)
buff[j]=j;
ofstream os;
os.open("a:edata.dat", ios::trunc|ios::binary);
if(!os)
{cerr<<"could not open output file\n"; return;}
cout<<"writing..."<<endl;
os.write(reinterpret_cast<char*>(buff), MAX*sizeof(int));

Reacting to Errors

17

if(!os)
{cerr<<"could not write to file\n"; return;}
os.close();
for(j=0; j<MAX; j++)
buff[j]=0;
ifstream is("a:edata.dat", ios::binary);
if(!is)
{cerr<<"could not open input file\n"; return;}
cout<<"reading..."<<endl;
is.read(reinterpret_cast<char*>(buff), MAX*sizeof(int));
if(!is)
{cerr<<"could not read from file\n"; return;}
for(j=0; j<MAX; j++){
if(buff[j]!=j)
{cerr<<"data is incorrect"<<endl; return;}
}
cout<<"data is correct"<<endl;
}

Reacting to Errors
In this example we determined whether an error
occurred in an I/O operation by examining the return
value of the entire stream object.
Example
if(!is)
//error occurred
is returns a pointer value if everything went well, but 0
if it didnt.
No matter what the errors is, its detected in the same
way and the same action is taken.
18

Analyzing Errors
It is also possible, using the ios error-status
flags, to find out more specific information
about a file I/O error.

19

Analyzing Errors
void main() {
ifstream is;
is.open("data.dat", ios::binary);
if(!is)
{cerr<<"can't open data.dat file\n";}
else
cout<<"file opened successfully"<<endl;
cout<<"file = "<<is<<endl;
cout<<"error state = "<<is.rdstate()<<endl;
cout<<"good() = "<<is.good()<<endl;
cout<<"eof() = "<<is.eof()<<endl;
cout<<"fail() = "<<is.fail()<<endl;
cout<<"bad() = "<<is.bad()<<endl;
}

20

can't open data.dat file


file = 00000000
error state = 2
good() = 0
eof() = 0
fail() = 1
bad() = 0
file opened successfully
file = 0012FF40
error state = 0
good() = 1
eof() = 0
fail() = 0
bad() = 0

Potrebbero piacerti anche