Download presentation
Presentation is loading. Please wait.
1
STREAM HANDLING
2
The I/O system in C++ is designed to work with a variety of including terminals, disks and tape drives. Although each device is different, the I/O system supplies an interface to the programmer the actual device being accessed. This interface is ‘stream’. Stream is a sequence of bytes. It acts either as a source from which the input data can be obtained or as a destination to which the output data can be sent. Source stream is input stream and destination stream that receives output is the output stream. C++ provides with a library of classes that have the functionality to implement various aspects of stream handling. Hierarchy is shown below:
3
Class ‘ios’ is the base class.
istream ostream ifstream iostream ofstream Istream_withassign fstream Ostream_withassign Class ‘ios’ is the base class. ‘ostream’ is derived from ‘ios’ and handles the general output stream. The insertion operator is defined and overloaded in this class to handle output streams from program variables to output files. ‘ostream_withassign’is derived from ‘ostream’.
4
cout is an object of the class ‘ostream_withassign’ and stands for console output. C++ treats (peripherals) monitor as file and ‘cout’ represents the monitor. cout<< x ; is translated as – ‘insert the stream ‘x’ from program variable in to the file called ‘cout’ ’. ‘istream’ is derived from ‘ios’ and handles the general input streams. Extraction operator is defined and overloaded in the class ‘istream’ to handle input streams from input files to program variables. ‘istream_withassign’ is derived from the ‘istream’. ‘cin’ is the object of that class and stands for console input. ‘cin’ represents the keyboard.
5
cin >> x; is translated as - extract the stream from the file and place it in the program variable ‘x’. The class ‘iostream’ is derived from multiple inheritance fro ‘istream’ and ‘ostream’. It has the functionality to handle both input & output streams Class ‘ofstream’ is derived from ‘ostream’, having the functionality to handle output streams to disk files. Objects of ‘ofstream’ represent output files on the disk. ofstream ofile (“first.dat”); this code opens a file for output (argument is passed as a string to the constructor of the class ). Since the insertion operator is defined in the base class of ‘ofstream’ the object ‘ofile’ can be passed
6
as the LHS operand instead of ‘cout’ ofile<<x; this is translated as “insert the stream from the program variable ‘x’ in to the file ‘first.dat’ ” . Class ‘ifstream’ is derived from ‘istream’ to handle input streams from disk files. Objects of ‘ifstream’ represent input files on the disk ifstream iflie(“first.dat”); opens a disk file for input. Since >>is defined in base class ‘ifstream’ the object ‘ifile’ can be passed as lhs operand. ifile >> x ; translated as – “ extract stream from file and place it in the program variable ‘x’. ‘fstream’ is derived from class ‘iostream’ and can handle both input and output streams from and to disk files.
7
The classes for handling streams to and from disk files are defined in the header file ‘fstream.h’ For handling general streams in ‘iostream.h’ Header file ‘iostream.h’ is included in ‘fstream.h’ Text and binary input/output How data is stored in memory? During runtime, the value of char variable is stored in memory as the binary equivalent of it ASCII equivalent. But value of int, float or double type is simply stored in its binary equivalent. Value of char ‘A’ is stored in one byte (number 65, ASCII equivalent of ‘A’, in base 2). If it is integer, then it is stored in four bytes, bits representing 65,base 2
8
There is no difference between text mode I/O and binary mode I/O with respect to character type variables. In both modes value is copied to/from memory /output or input file as it is. Numeric data needs to be output in base 10(text) format which is in base 2 format in memory – requires transformation in representation of data. Standard library functions will handle this. Suppose an integer value ‘65’ is stored in memory occupying four bytes. It will occupy the same bit setting in the output disk file, if it is copied by an output function that outputs in binary mode. If the same function outputs to monitor, instead of
9
disk file, the value ‘A’ followed by three blank spaces will be displayed. But we would like to see ‘65’ and not ‘A’. If the same value is copied by an output function that outputs in text mode, it will occupy two bytes with different bit settings, in the output file. First byte will represent ‘6’ and the second ‘5’. In case of input, if the input value is in text mode it should be copied to memory after transforming to binary mode. If in binary mode then simply copy. Text mode is suitable for console I/O because they are in base 10 format with which we are accustomed.
10
Text and binary files In text files, binary data (numeric data that is stored in base 2 format in memory) is stored in base 10 format. In binary files the same binary data is stored in base 2 format. Binary/text is the mode in which the data is written into the files defines the nature. The size of output file containing integer values is always multiple of four. The c++ standard library provides functions that input in binary mode. These function require the address of the variable whose data needs to be input along with its size. The size of the block of bytes this code reads is equal to the supplied size
11
The binary functions that write data into disk files need not insert an artificial delimiter while the data is output. (treat the size as the delimiter) In text mode, the records stored in the output file are of variable lengths. ‘1’ occupies one byte, ‘11’ two bytes and so on in disk file, although each occupies four bytes in memory. In case values are output in text mode, size of the output value is not fixed. Hence size can not be used as the delimiter. To ensure the correct interpretation of the value, the code calls a text mode function for output should also insert a delimiter of choice in the output file after every call
12
There should be no chance of delimiting character itself becoming a part of the output value any time in future. The size of file does not indicate the number of records stored in it.(record size not fixed) Text input / output The insertion operator : - is defined and overloaded in the class ‘ostream’. It takes an object of class ‘ostream’ or an object of a derived class from that, as LHS operand. RHS operand is one of the values of built in types. Inserting characters into output streams using the insertion operator:- character value occupies 1 byte in memory and same in output file in text mode
13
#include<fstream.h>
void main() { char cVar; ofstream ofile (“first.dat”); cVar = ‘A’ ; ofile << cVar; } Last statement copies the values of cVar from memory to the disk file without transforming. Inserting integers into output streams using the insertion operator: { int iVar; ofstream ofile (“first.dat”); iVar = 111 ; ofile << iVar; }
14
Integer occupies 4 bytes in memory
Integer occupies 4 bytes in memory. In text mode it depends upon its value. ‘111’ will occupy 3 bytes. Inserting float and double into output streams using the insertion operator:- It is same as inserting integers into output streams using the insertion operator ‘1.111’ occupy 5 bytes. #include<fstream.h> void main() { int fVar; ofstream ofile (“first.dat”); fVar = ; ofile << fVar; } Inserting strings into output streams using the insertion operator:- A character array is allocated
15
a fixed number of bytes in the memory during run time
a fixed number of bytes in the memory during run time. However the actual string contained in it usually occupies only part of that memory. For example char cArr[20]=“abcd”; When this is output by ‘<<‘ it will occupy only 4 bytes in file. void main() { char cArr[20]=“abcd”; ofstream ofile (“first.dat”); ofile << cArrVar; } Inserting objects into output streams using the insertion operator : we have to overload the operator for that class.
16
The put() function : is a member of ‘ostream’ class
The put() function : is a member of ‘ostream’ class. Its prototype is – ostream & ostream:: put(char c) The function can be called with respect to an object of the class ‘ostream’ or its derived classes. One such object is ‘cout’ The function copies the character that is passed as a parameter to it in to the output file associated with the object with respect to which the function is called. void main() { ofstream ofile (“first.dat”); ofile.put(‘a’); } Character ‘a’ is written in to the file
17
void main() { cout.put(‘a’); } //display ‘a’ on the monitor The difference between the insertion operator and put() function is that while the former modifies the format of the output with respect to the manipulators set earlier, the latter simply ignores format manipulator settings. Text input: It is achieved by (i) extraction operator (ii) get() function (iii) getline() function Extraction operator can be used to input values from disk files and inputs in text mode It has been defined and overloaded in the class
18
‘istream’. It takes an object of the class ‘istream’ /its derived classes as its LHS operand. It takes a variable of one of the fundamental data types as its RHS operand. It copies the value found at the current location in the file that is associated with the object on its left in to the variable on its right. Extracting characters from input streams using the extraction operator: if the RHS operand is a char type variable, it reads one byte from the input file #include<fstream.h> void main() { ifstream ifile (“first.dat”); char cVar; ifile >> cVar; cout<<cVar; }
19
that is attached with the object on its left and writes it into the variable.
Extracting integers from input streams using the extraction operator: if the RHS operand is an integer type variable, it reads one byte from the input file that is attached with the object on its left until it finds a white space. The extraction operator converts the read value(in base 10 format) into base 2 format and writes into the variable. #include<fstream.h> //input : void main() { ifstream ifile (“first.dat”); int iVar; ifile >> iVar; cout<<iVar; } //output: 11
20
Extracting floats and doubles from input streams using the extraction operator: in the same way as they are for integer type variables. Extracting strings from input streams using the extraction operator: As in the case of integers, it reads from the file until it finds a white space while reading value for a character array. #include<fstream.h> //input : abc def ghi void main() { ifstream ifile (“first.dat”); char cArr[20]; ifile >> cArr; cout<<cArr; } //output: abc Extracting objects from input streams using the extraction operator:have to overload it for that class
21
The get() function It has been defined in the class ‘istream’. It reads one byte from the input file and stores it in the character variable that is passed as a parameter to it. Prototype is : istream & istream::get(char&); #include<fstream.h> //contents of file : abcd void main() { ifstream ifile (“first.dat”); char cVar; ifile.get(cVar); cout<<cVar; } //output: a The getline() function It reads one line from the input file. Defined in class ‘istream’. It takes three parameters. The prototype – istream & istream :: getline (char * , int, char=‘\n’)
22
The first parameter is the name of the array in which the read line will be stored. Second is an integer, signifies the number of bytes that will be read from the input file. Third one is the delimiting character, prevents from reading further. #include<iostream.h> //read from key board void main() { char cArr[20]; cout<<“Enter a string:”; cin.getline(cArr,6,#); cout<<“you entered :” <<cArr <<endl; } output: Enter a string :abcdefgh /abc#de/aa bb cc you entrred : abcde /abc/aa bb It reads bytes one less than the second parameter
23
or till it encounters the delimiting character whichever occurs earlier. It reads white space also. It reads from the keyboard buffer and leaves behind the unread bytes in the buffer itself. #include<iostream.h> void main() { char cArr[20]; ifstream ifile(“first.dat”); ifile.getline(cArr,6,#); cout<<“you read from file :” <<cArr <<endl; } output: you read from file :abcde /abc / aa bb It works in a similer fashion when it reads from disk files. If the contents of file : abcdefgh / abc#def or aa bb cc then the output would be as above
24
Binary Input/ output The write() function : - It copies the values of variables from the memory to the specified output file. It works in binary mode. Binary mode functions are not concerned about the data types of the variables that is output. They are only interested in the address of the variable and the size of the variable. Prototype of write() is:– ostream & ostream :: write (const char * , int ) It has been declared in the ‘ostream’ class and takes two parameters. First one is the address of the variable and the second one is the size. It writes the value of variable to the file, associated with object.
25
Inserting characters into output streams using the write() function:- following functions illustrate how the write() can be used to output the value to a disk file and monitor. There is no difference between outputting a char type value in text & binary mode. #include<fstream.h> //to disk file void main() { ofstream ofile (“first.dat”); char cVar; cVar=‘a’; ofile.write(&cVar,sizeof(char)); } #include<iostream.h> //to monitor void main() { char cVar; cVar=‘a’; cout.write (&cVar, sizeof (char) ) ; } //output: a
26
Inserting integers into output streams using the write() function: the value contained in four bytes that are occupied by ‘iVar’ will copied to the designated output file without any transformation #include<fstream.h> //to disk file void main() { ofstream ofile (“first.dat”); int iVar; iVar=65; ofile.write((char*)&iVar, sizeof(int)); } #include<iostream.h> //to monitor void main() { int iVar; iVar=65; cout.write((char*)&iVar, sizeof(int)); } output : A
27
The monitor shows the ASCII equivalent of each of the bytes passed to it.
The difference between outputting an integer type value in text mode(put()) and binary mode (write()) is – in the former, the read value is transformed to base 10 format and then copied to output file. There is no such conversion in the latter case. Inserting floats and doubles into output streams using the write() function: same as integer type. Inserting strings into output streams using the write() function:- the name of the array is the starting address and the second parameter is the size of memory block whose value is to be written
28
into the output file. Since 10 is the size it copies one byte at the end with junk value.
#include<fstream.h> //to disk file void main() { ostream ofile (“first.dat”); char cArr[10]=“abcdefgh”; ofile.write(cArr, sizeof(cArr)); } #include<fstream.h> //to monitor void main() { char cArr[10]=“abcdefgh”; cout.write(cArr, strlen(cArr)); } output:abcdefgh Inserting objects in binary mode:- value of the object in memory block is copied to file
29
#include<fstream.h> //to disk file class A { //dfefinition of class A } void main() { A A1 ; ostream ofile (“first.dat”); ofile.write((char*) &A1, sizeof(A)); } The value of the object is directly accessed by a non- member function and c++ does not prevent explicit typecasting of an object’s address. This is allowed – char* cptr = (char * )&A1; ofile.write((char*) &S1, sizeof(String)); when this code is executed for string object, instead of string, the pointer cStr is copied to the file. When this value is later read through another program,
30
it would end up with a location where the string no longer exists
it would end up with a location where the string no longer exists! Hence client programs are not supposed to know how the actual data is managed. Objects should be responsible for outputting their own data (linked lists, vectors, trees etc. ) Binary input : read() It copies the values from the specified input file to the memory block occupied by the target variable. It works in binary mode. It accepts the address of the variable and the size of the variable . Prototype is – istream & istream :: read (char*, int) ; it is from class ‘istream’. First parameter is the address of the variable into which the read value
31
needs to be input. Second parameter is the size of the variable.
Extracting characters from input streams using the read() function:- if contents of file are : xyz #include<fstream.h> //read from disk file void main() { ifstream ifile (“first.dat”); char cVar; ifile.read(&cVar,sizeof(char)); cout<<cVar; } //output: x #include<fstream.h> // read from console void main() { char cVar; cout<<“Enter a character:”; cin.read(&cVar, sizeof (char) ) ; cout<<cVar; }
32
There is no difference between inputting a character type value in text mode (extraction operator, get() ) and in binary mode( read() ). There is no conversion in either case. Extracting integers from input streams using the read() function:- if first four bytes contain 64 #include<fstream.h> //read from disk file void main() { ifstream ifile (“first.dat”); int iVar; ifile.read ( (char *)&iVar, sizeof(int) ); cout<<iVar; } //output: It copies the read value into the memory block the address of whose first byte is that of first parameter
33
To read the value of an integer from the keyboard, reads four bytes from the keyboard, not converts in any way and copy them into the four bytes that are occupied by the target integer type variable. #include<fstream.h> //read from disk file void main() { int iVar; cout<<“Enter a value in base2 format:”; cin.read ( (char *)&iVar, sizeof(int)); iVar=iVar&0x000000ff; //to input zeros in the upper cout<<iVar; } //three bytes of 4 bytes of iVar output: Enter a number in base2 format: ABCD Extracting floats is same as integers
34
Extracting strings from input streams using the read() function:- contents of ‘first.dat’- abcdef
#include<fstream.h> //read from disk file void main() { ifstream ifile (“first.dat”); char cArr[20]=“123456”; ifile.read(cArr,3); cout<<cArr<<endl; } //output: abc456 ‘3’ has been passed as the second parameter. Hence it reads only 3 characters. First parameter is the name of the array and the 3 characters read from the beginning of the file are copied to array. Extracting objects from input streams using the read() function:- The following statement reads
35
file.read ((char*) &A1,sizeof(A));
the data from file and loads back to an object. In case of complex objects, we need to have the function that reads the entire data from disk files. Opening and closing files: The open() function: - This function is provided in both ‘istream’ and ‘ostream’ classes. Syntax is ofile.open(“first.dat”); ifile.open(“first.dat”); A second parameter (known as ‘open mode’) an integer value can also be passed to this function ios:app - for appending to end of file ios:ate – for going to end of file on opening ios:binary – for opening a binary file
36
ios:in – for opening a file for reading only
ios:nocreate – for causing open to fail if the file does not exist ios:noreplace – for causing open to fail if the file does already exists ios:out – for opening a file for writing only ios:trunc – for deleting contents of the file if it exists The constructor of ‘ostream’ takes ‘ios:out’ as the default value for second parameter. Also ‘istream’ takes ‘ios:in’ default. The above constants can be meaningfully combined using bitwise OR (|) ofile . open (“first.dat” , ios:app | ios:nocreate ) ;
37
The close() function : - closing the file with in a program may be needed when we want to write in to a file that we have opened for reading and vice versa. It is defined in both ‘istream’ and ‘ostream’. Syntax is - ofile.close(); The overloaded version of open() for the ‘fstream’ class does not take a default value for the second parameter. We have to specify explicitly whether we want to open the file for reading or writing or both. Iofile.open(“first.dat” , ios:in| ios: out ) ;//for both File pointers : - are created and maintained for open files during runtime. There are two file pointers – the ‘put’ pointer and the ‘get’ pointer.
38
These can be explicitly manipulated by the use of some functions that are the members of stream handling classes. The seekp() function:- is used to make the put pointer point at a desired position in the open file. By default it points at the beginning if it is newly opened for writing. In case of existing file opened for appending, it points at the end. Every write operation pushes forward the put pointer by the number of bytes written. It is defined in ‘ostream’ and has two versions ostream& ostream :: seekp( streampos pos) ; and ::seekp(streamoff off, ios:seek_dir dir) ;
39
In the first version, it takes only one parameter, the absolute position with respect to the beginning of the file. Type ‘streampos’ is type defined with ‘long’. Numbering of the position starts from zero ofile.seekp(1); put pointer points at second byte. The second version takes two parameters – first one is the offset and the second one is the position in the open file with respect to which the offset is being specified. Type ‘ios:seek_dir’ is an enumerated type with values ios:beg, cur and end . ofile.seekp(-1, ios:end); - points at the last byte ofile.seekp(0, ios:beg); - points at the beginning ofile.seekp(2, ios:beg); - points at the third byte
40
ofile.seekp(-2, ios:cur); - points at two bytes to the left from its current position ofile.seekp(0, ios:end); - points at past the last byte Difference between ‘app’ and ‘ate’ flags : - neither of the two overwrites an existing file. ‘ate’ allows you to rewind the put pointer and modify the existing contents of the file, where as ‘app’ does not allow this. It points at the end of the file, as you append it moves forward. It can not be rewound. The tellp() function :- it returns the current position of the put pointer. Defined in class ‘ostream’ with syntax – streampos ostream :: tellp() ; To determine the current position of the put pointer and store in a variable long pos =ofile.tellp();
41
The seekg() function:- used to explicitely make the get pointer at a desired position in the open file. By default the get pointer points at the beginning of the file that is opened for reading. Every read operation pushes forward the get pointer by the number of byte reads. Defined in class ‘istream’ istream & istream :: seekg(streampos pos); istream & istream :: seekg(streamoff off, ios::seek_dir dir ); //explanation similar to seekp() The tellg() function:- like tellp() it returns the current position of get pointer. Defined in ’istream’. Streampos istream :: tellg() ; //syntax long pos = ifile.tellg(); // to store position in a program variable
42
Random access to files Seekp() and seekg() functions are used for random access. iofile is an object of class ‘fstream’ iofile.seekp( (n-1)* sizeof(int), ios::beg ); This statement causes the file pointer to point at the nth record. This works if the size of all records in the file is equal. Possible only if binary data is stored in binary mode. To find the number of records iofile.seekp(0,ios::end) ; long lsize= iofile.tellp(); int iNoOfRec = lSize / sizeof(int);
43
Object input/output through member functions
Classes that have pointers that point at externally held data should also have the necessary functionality to output and input their data . class String //#include<fstream.h> { … public: … void diskOut (ostream & fout) { fout.write(( char *) & len, sizeof(int); for(int i=0; i<len; i++) { fout.put(cStr[i]); } } void diskIn (istream & fin) { String temp; // input the string’s length fin.read( (char *)& temp.len, sizeof(int) ); temp.cStr = new char(temp.len+1);
44
for ( int i=0; i<temp.len+1; i++ ) fin.get( temp.cStr[i] ) ; temp.cStr[i] = ‘\0’ ; *this = temp ; }; void main() String s1 ; s1.setcStr(“abcd”) ; ofstream ofile (“c:\\string.dat”) ; s1.diskOut(ofile) ; ofile.close() ; String s2; ifstream ifile (“c:\\string.dat”) ; s2.diskIn (ifile) ; cout<<s2.getcStr()<<endl ; ifile.close() ; } output: abcd
45
Error handling Error object of class ‘istream’, ‘ostream’ – contains three flags that indicate the state of next byte in the associated file (i) eofbit – becomes true if the eof is encountered (ii) failbit–becomes true if read/write operation fails (iii) badbit- becomes true if the file being read is corrupt beyond recovery The eof() function :- whenever the file pointer encounters the end of file mark while reading the file, it sets the value of ‘eofbit’ to true. It returns the result of past read. It does not looks ahead before returning the result. Hence the test is given at the
46
beginning of the loop. The fail() function :- it returns true if the file could not be opened for any reason. Whenever the open() fails to open a file, it sets the ‘failbit’ to true. Another reason is – the non-existence of the file that is being opened for reading or writing by using the ‘ios::nocreate’ flag. Also for the file being opened for writing by using ‘ios::noreplace’ flag but it already exists. Some other reasons are: The file being opened for writing is readonly. There is no space on the disk. The file being opened for writing is in a disk that is write-protected.
47
The bad() function:- it returns true whenever a function that is reading from a file encounters a serious I/O error. Under such circumstances, the value of the ‘badbit’ flag gets set to true. It is best to abort I/O operations on the stream in this situation. The clear() function:- it is used to clear the bits returned by the ‘bad()’ function. This is necessary under a number of circumstances. For example, when we use ‘iofile.eof()’ and the ‘eofbit’ sets to true, then we can not further continue the write operation unless we use the clear() function.
48
Manipulators :- are used to format the output
Manipulators :- are used to format the output. Pre-defined manipulators are available and the programmer can create his own. Manipulators can be inserted in an output stream just like values are inserted for output. out<<manip1<<manip2<<value1<<manip3<<value2; out is the object of the class ‘ostream’. ‘cout’ can also be used to format the output to the monitor. Predefined manipulators: The setw() manipulator: - takes an integer type variable as its only parameter. This specifies the width of column within which the next output will be output. If the value that is output after this
49
manipulator is passed in the ‘insertion’ stream occupies less number of bytes than the specified parameter, then extra space will be created in the column that will contain the output value. The extra space will be padded by blanks or by the character that is passed as a parameter to the ‘setfill()’ func. cout<<123<<enbdl; cout<<setw(3)<<10; output will be : the setw() manipulator has to be used separately for each item to be displayed. cout<<setw(5)<<10<<setw(5)<<234<<endl; no truncation of data occurs if the parameter that is passed to the setw() function is not sufficient to hold the data that is output subsequently. Instead,
50
the padding requirement implied by the setw() function is ignored.
The setprecision() manipulator: - by default, c++ displays the values of float and double type with six digits after the decimal point. However we can pass the number of digits we want after the decimal point as a parameter to the manipulator. cout<<setprecision(3)<<sqrt(3)<<endl<< ; output : 1.732 unlike the setw(), setprecision() retains its effect even after outputting the value. Setfill() manipulator:- we can specify the padding caharacter by passing it as a parameter
51
cout<<setfill(‘
cout<<setfill(‘*’)<<setw(5)<<10<<setw(5)234<<endl; output : ***10**234 The setiosflags() manipulator:- it is also used to format the manner in which the output data is displayed. The two parameters it takes are ‘ios::showpos’ and ‘ios::showpoint’ . ‘ios::showpos’ ensures that the positive sign is prefixed to numeric data when they are displayed cout<<setiosflags(ios:: showpos)<<10; output: the ‘ios::showpoint’ ensures that the number of significant digits in the value being output is less than that specified by the ‘setprecision()’ manipulator , then the extra spaces obtained
52
there by are filled with zeros. cout<<setprecision(3)<<2
there by are filled with zeros cout<<setprecision(3)<<2.5<<endl <<setiosflags(ios::showpoint)<<2.5<<endl; output: 2.5 2.500 The resetiosflags() manipulator:- this cancels the effect of the parameter that was passed to an earlier call to the setiosflags() manipulator Cout<<setprecision(3) <<2.5<<endl <<setiosflags(ios::showpoint)<<2.5<<endl <<resetiosflags(ios::showpoint)<<2.5<<endl; output: 2.5
53
User-defined manipulators :- can be done by defining a function as follows: ostream & <manipulator> (ostream & out ) { /*statementsa*/ return out; } an example ostream & currency ( ostream & out) { out<<“$. ”; return out; } now if we write cout << currency << 20 ; output : $ these enable modularity. It can be used throughout an application to format the output in a uniform manner. If change is required, it needs to be carried out at only one place- the definition of the manipulator and again the change occurs uniformly through out the application.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.