13

IO Streaming

LEARNING OBJECTIVES

At the end of the chapter, you will be able to understand and program

  • Unformatted and formatted stream operators.

  • Use IO manipulator to format output.

  • Sequential and random/direct access file handling.

  • Read objects from and write objects onto a file

13.1 Introduction

What crosses your mind when you think of streams? Probably streams of water, we call them springs, flowing from the top of a hill to plains. In C++, we call streams or IO streams.

This chapter will introduce to you unformatted and formatted input and output streams. It deals extensively with stream manipulators that are used to format and control stream data. The chapter also concentrates on file handling in C++ through <fstream> header file. The concepts covered are sequential file handling and random/direct access techniques. The techniques to handle formatted data and raw data are discussed. We will wrap up the chapter with object read and write operations onto a file.

13.2 IO Streaming

In C++, IO streams are flow of bytes from one input device to memory and vice versa. A stream is like a pipe. It can carry anything in the pipe, be it kerosene, milk, water, etc. – refer to Figure 13.1 shown below.

 

Streams – A concept

 

Figure 13.1 Streams – A concept

 

IO Streaming – A close look

 

Figure 13.2 IO Streaming – A close look

 

Streams output whatever is inputted.

  • Byte Stream int in: int out
  • string in: string out
  • object in: object out

13.3 IO Library Files Classification

The library functions are classified as Console IO, Disk IO and Port IO. Port IO are used for input and output programming, when we want to use ports for data input and output.

Disk IO: This mode of operation is performed on entities called files. Usually, writing onto files and reading from the files are never done directly onto disk. Instead, a buffer (a memory) is used to store prior to writing onto file and after reading from the file. Buffering in case of Disk IO is essential for saving access time required to access memory. DiskIO is of two types:

  • High-level disk IO also called standard IO/Stream IO: Buffer management is done by the compiler/operating system.
  • Low-level disk IO also called system IO: Buffer management is to be taken care of by the programmer.

Console IO: All the input and output functions control the way input has to be fed and the way output looks on standard output devices, i.e. screen. These IO statements are further classified as formatted and unformatted.

  • Formatted IO: We use cin and cout objects. We specify the format formatting commands of C++.
  • Unformatted IO: The unformatted category for input and output.

13.3.1 Formatted IO

In order to perform I/O operations, a stream is attached to an I/O device. Typical I/O devices include consoles, keyboards, files and electronic devices like sensors. The inserters represented by the “<<” symbol work as translators which translate in memory representation of data types such as integers, floats and user-defined data types into data types which can be understood by the I/O devices. The extractor represented by the “>>” symbol translates data sent by I/O devices to in memory representation formats such as integers and floats. Typical I/O devices like consoles and keyboards send and receive data in ASCI format.

Let us see with an example how extractors and inserters work. Consider the following piece of code int n; cin >> n; Now using the keyboard, assume the user has entered numbers 6, 7 and 8 followed by the enter key. Following this operation, the buffer associated with the input stream would look like Figure 13.3.

 

Representations of input stream

 

Figure 13.3 Representations of input stream

 

ASCII representation of individual numbers is as follows:

      6 = 0 × 36 = 0011 0110   7 = 0 × 37 = 0011 0111   8 = 0 × 38 = 0011 1000

Through the statement cin >> n extractor knows that the input stream should be formatted into an integer as n is of the type integer. The extractor then proceeds to extract each character from the stream and converts it into decimal value. To get equivalent decimal values from ASCII format, the extractor subtracts ASCII value of 0(0 × 30) from each character in the stream.

   ‘6’ – ‘0’ = 0 × 36 – 0 × 30 = 6 : ‘7’ – ‘0’ = 0 × 37 – 0 × 30 = 7 : ‘8’ – ‘0’ = 0 × 38 – 0 × 30 = 8

The extractor continues to do the above operation till it encounters ‘ ’, carriage return (CR) in the input stream. It also stops extracting if it encounters Tab, Space and EOF markers. During extraction, the extraction operator also keeps a count of numbers or characters it has extracted and accordingly sets the place value of each digit. In our case, 6 is assigned a place value of 100, 7 a place value of 10, and 8 a place value of 1. The last step involves multiplying the extracted decimal values with their corresponding place values and adding them up to get integer representation: n = 6*100 + 7*10 + 8*1 = 678. But in memory, representation is in the form of integer, so 678 will be represented as:

      678 = 0 × 2A6 = 0000 0010 1010 0110.

The inserter works in exactly the opposite way. As seen from the above example, iostream library object cin coupled with the extractor operator >> provides the user translation services and also the processing of special characters such as Carriage Return(CR), Space, Tabs and End of File(EOF). This kind of I/O is called formatted or high-level I/O. Formatted I/O abstracts the user from inner workings of streams and is easier to use. The disadvantage of formatted I/O is that it is slow and not suitable for large data sizes.

13.3.2 Unformatted IO

Unformatted I/O is also called low-level I/O. It offers the highest efficiency and throughput amongst all the other I/O mechanisms. Unlike formatted I/O, here input has no automatic whitespace, Tab, carriage return detection and processing, and also data is not formatted – the programmer has to interpret the data.

Input:

get():

  • Reads a character from stream including delimiters like white spaces, EOF markers and returns it.
  • Usage cin.get()

get(char& ch):

  • Reads a character from stream and stores it in ch
  • Usage cin.get()

get(char* str, int count, char delim=’ ’):

  • Function reads count-1 characters or till it encounters the delimiter character in the stream and stores the characters in the str buffer.
  • When the delimiter is encountered, it is not copied into the str buffer. It remains in the input stream
  • Null character is inserted in the array str
  • delimiter has to be flushed from stream else it will remain in the stream
  • Usage cin.get(buffer, count) //when you want to use default delimiter ‘ ’
  • Usage cin.get(buffer, count, ‘#’) //when you want to use different delimiter

getline(char* str, int count, char delim=’ ’):

  • Operates like get(char* str, int count, char delim= ’ ’):
  • When the delimiter is encountered, it is not copied into the str buffer but unlike get(), getline() discards delimiter from stream
  • Usage: similar to get(char* str, int count, char delim=’ ’)

read(char* str, int count) :

  • Function reads count characters from the stream and place in array str.
  • Unlike the formatted I/O functions read does not append string termination character to the buffer str.
  • If EOF marker is encountered during read operation function returns error.

 

Output:

put(char ch):

  • Function writes the character ch to the stream.
  • Usage: cout.put(ch);

write(const char* str, int count):

  • Functions writes count characters from the buffer str to the stream.
  • Write operation does not terminate for any of the delimiters.
  • Precautions should be taken to ensure count number of characters are present in the buffer str.
  • Usage: cout.write(str, count)

Miscellaneous:

putback(char c)

  • Places the character c obtained by get() back in to the stream.

peek()

  • Returns the next character from the stream without removing it

ignore( streamsize num=1, int delim=EOF ):

  • Skips over a designated number of characters (default is 1)
  • Terminates upon encountering a designated delimiter (default is EOF)

Consider the following piece of code:

  cout <<”
 Enter source file name..: “;
  cin>>filename;
  cout<<”
 Enter text for inputting to file …”<<endl;
  cin.ignore(1,’
’);
  cin.getline(text,80);

Now suppose you have entered thunder.txt and pressed enter at the first prompt the operation cin>>filename reads the input stream stores filename with the value thunder.txt but the cin operator does not extract the extra enter (‘ ’) key that you have inputted. Now suppose that we do not include cin.ignore(1,’ ’) and directly call cin.getline(text,80), it will return NULL as first character in the stream is ‘ ’ the default delimiter for getline(). To avert this situation, we ignore the operation to discard the ‘ ’ character present in the input stream.

 

Example 13.1:   unformatedio1.cpp Program to Show cin.get()) to Read a Character

1.  #include<iostream>
2.  #include<cstring>
3.  using namespace std;
4.  void main()
5.  {char ch, str[10];
6.  cout<<”
 Enter any string : Showing character input thru cin.get() :”;
7.  while((ch = cin.get()) != ‘
’) // using get() function
8.  cout << ch;
9.  cout<<”
 Enter a string<Less Than 9 or less characters : cin.read>: “; //using read fn
10. cin.read(str, sizeof(str));
11. str[9] = ‘’;
12. cout << endl << str;
13. }
/*Output: Enter any string: Showing character input through cin.get() :Hello World
Hello World
Enter a string<Less Than 9 or less characters : cin.read>: hello USA*
Line No 7 Shown cin.get() . Line No 10 shows cin.read() . Note that read() also works with cin object.

 

Example 13.2:   unformatio2.cpp Program to Show Unformatted Output Functions

1.  hello USA*/
2.  #include<iostream>
3.  #include<conio.h>
4.  #include<string.h>
5.  using namespace std;
6.  void main()
7.  { int i;
8.  char str[] = “I enjoy programming in C++” ;
9.  for(i = 0 ; str[i] != ‘’; i++) cout.put(str[i]); //using write function
10. cout<<endl; cout.write(str, strlen(str)); getch();
11. }
/*Output I enjoy programming in C++ I enjoy programming in C++*/
Line No 9 shows usage of cout.write(). Note that write works with cout also.

13.3.3 IO Stream State

I/O library in C++ provides a mechanism to test whether a particular I/O operation has succeeded or failed. Each stream object maintains a set of flags which indicate the state of the stream after an I/O operation. Library also provides set of member functions which can be used to test the flags. The flags and the corresponding member functions are shown in the Table 13.1.

 

Table 13.1 Flags and member fuctions

Flag Name Description Testing Function
goodbit Set to 1 when stream encounters no errors

good()

Ex: cin.good()

eofbit Set to 1 when stream encounters end of file

eof()

Ex: cin.eof()

failbit Set to 1 when stream encounters an error but is recoverable

fail()

Ex: cin.fail()

badbit Set to 1 when stream is corrupted and is unrecoverable

bad()

Ex:cin.bad()

 

Example 13.3:   streamstate.cpp Program to Show Reading Stream State Flags

#include<iostream>
#include<conio.h>
using namespace std;
void main()
{int value;
 cout << “Enter Value: “;cin >> value;
cout <<endl <<”goodbit: “<< cin.good();cout <<endl <<”eofbit : “<< cin.eof();
cout <<endl <<”failbit: “<< cin.fail();cout <<endl <<”badbit : “<< cin.bad();
cout <<endl <<"Enter Value(enter characters to see effect on flags): ";cin >> value;
cout <<endl <<"goodbit: "<< cin.good();cout <<endl <<"eofbit : "<< cin.eof();
cout <<endl <<”failbit: “<< cin.fail();cout <<endl <<”badbit : “<< cin.bad();
getch();
}
/* Output : Enter Value: 47 goodbit: 1eofbit : 0failbit: 0badbit : 0
Enter Value(enter characters to see effect on flags): ghj :
goodbit: 0eofbit : 0failbit: 1badbit : 0*/

13.3.4 IO Stream Library – Header Files

The <iostream> header file allows byte of data to flow from source to destination. Stream is independent of what data type is getting streamed or the source of destination.

C++ supports istream for input and ostream for output. IO stream library includes four types of predefined streams:

cin   : for standard buffered input

cout : for standard buffered output

cerr : for unbuffered error output. Works just like cout

clog : for buffered log

<iomanip> header file consists of several functionalities to handle formatted output such as setw () setprecision(), etc.

<fstream> contains all the programs needed for file handling. The hierarchy of IO stream is shown in Figure 13.4.

 

IO stream class hierarchy

 

Figure 13.4 IO stream class hierarchy

 

Example 13.4:   io1.cpp Program to Show Cin and Cout at Work

#include<iostream>
using namespace std;
void main()
{double price; char title[30]; char author[30];
  char * tell = “ Enter the title of the Book, Author and price :”; cout<<tell;
  cin>>title>>author>>price; cout<<”
Tile of the book :”<<title<<endl;
  cout<<”
Author of the book :”<<author<<endl;
  cout<<”
Price of the book :”<<price<<endl;
}
/*Output :Enter the title of the Book, Author and price :C++ ramesh 250.00
Tile of the book :C++ : Author of the book :ramesh : Price of the book :250*/

13.4 IO Manipulators

Manipulators alter the status of streams. For using this feature we need to include the statement: #include<iomanip> in global section. For example, if we use a manipulator setprecision(2), all the floating point variable output will be two digits after decimal point. A few of the important IO manipulator are:

cout<<dec<<intvar;decimal / hexa / octal representation from integers
cout<<hex; cout <<oct;
cout<<setiosflags(ios::dec) Sets the formatting bits as decimal
cout<<resetiosflags(ios::hex) Resets already set flags as per format specified
cout<<setbase(int n) :Sets bas to n
cout<<setw(int n) :specifies width for output formatting
cout<<setfill(“*”); :fills the unfilled space set with setw() with fill character

Character manipulators are shown in Table 13.2. Numberic and Data stream manipulators are shown in Tables 13.3 and 13.4, respectively.

 

Table 13.2 Character manipulators

Manipulator Affected Flag Description
setw(val) None Sets the width of output filed to the specified value
setfil(char) None Pads the unfilled width of the output with the specified character
right ios::right Right justifies the output
left ios::left Left justifies the output
internal ios::internal Left adjusts the sign and right adjusts the value

 

Table 13.3 Numeric manipulators

Manipulator Affected Flag Description
dec ios::dec I/O uses decimal notation for input and output
hex ios::hex I/O uses hexadecimal notation for input and output
oct ios::oct I/O uses octal notation for input and output
scientific ios::scientific Display floating point number in scientific notation
fixed ios::fixed Display floating point number in fixed notation
setprecision(n) None Sets precision of floating point variables to n

 

Table 13.4 Data stream manipulators

Manipulator Affected Flag Description
endl None Inserts newline character in the stream and flushes (sends) the buffer to output
flush None Flush the output buffer to the console
ws None Ignore white spaces in the input
cout<<endl; :new line to iostream and flushes the buffer.
cout<<flush; :flushes ostream buffer
cout<<ends; :inserts null character at the end

Method 1: Using setiosflags to manipulate flags

cout<< setiosflags(ios::left);
cout << setw(10) << setfill(‘.’) << “Hello” ;

Method 2: Using Manipulators

cout << left <<setw(10)<<setfill(‘.’)<<”Hello” ;

 

Example 13.5:   io2.cpp Program to Show Cin and Cout at Work

1.  #include<iostream>
2.  #include<iomanip>
3.  using namespace std;
4.  void main()
5.  {double price; char title[30]; char author[30]; int copies;
6.  char * tell1 = “ Enter the title of the Book :”;
7.  char *tell2 = “ Enter the Author of the Book :”;
8.  char *tell3 = “ Enter the price of the Book :”;
9.  char *tell4 = “ Enter No of copies of the Book :”;
10. cout<<tell1<<flush;
11. cin>>ws>>title; cout<<tell2<<flush; cin>>author; cout<<tell3 <<flush;
12. cin>>price; cout<<tell4<<flush; cin>>dec>>copies;
13. cout<<setiosflags(ios::left)<<”
Title of the book :”<<title <<endl;
14. cout<<”
Author of the book :”<<author<<endl;
15. cout<<resetiosflags(ios::right)<<”
Price of the book :”<<setw(10) <<price<<endl;
16. cout<<”
 Number of copies :”<<setw(10)<<copies<<endl;
17. }
/*Output: Enter the title of the Book :C++ : Enter the Author of the Book :Ramesh
Enter the price of the Book :250 :Enter No of copies of the Book : 10000
Title of the book :C++ :Author of the book :Ramesh : Price of the book :250
Number of copies :10000 */
Line No. 10: shows that we need to use flush() to flush the buffer on to IO device.
Line No. 11: instructs ws meaning accept white spaces while taking in title. Of course, once set, the flags continue to be set unless cancelled by altering the flag.
Line No. 12: shows flush() and decimal setting. Line No 13 shows left justification.
Line No. 15: shows setw(10) meaning width of 10. It also restsiosflag to right.

13.5 Flags

The arguments that can be passed to setiosflag and resetiosflags manipulators are shown below:

 

ios::skipws skip white spaces in input stream
ios::left or ios::right left or right justification
ios::scientific
ios::fixed follows decimal notation for floating point numbers
ios::hex,ios::oct
ios::showbase outputs the base number system
ios::showpoint shows decimal point compulsorily.
Ios::showposs shows + sign while displaying positive numbers

13.6 File I/O

We would come across files everywhere we go. For example, college holds a file for each of their students. Similarly municipality holds files containing details of taxes to be paid by citizens. Indeed files are so common in our lives, C++ language and other languages support files. What is a file? A file is a collection of records. Figure 13.2 shows a file named student.dat with n records belonging to n number of students.

A record in a physical file is a data sheet wherein details of a student are recorded. There will be as many records as there are students. In a C++ file too, there will be records, again one for each student. Figure 13.5 shows a record.

 

File and records

 

Figure 13.5 File and records

 

A record in turn contains fields. Figure 13.6 shows a record and fields contained therein.

 

Record and fields

 

Figure 13.6 Record and fields

13.6.1 File Types

Files can be classified based on the way they are accessed from the memory as

Sequential File: All records are stored sequentially as they are entered. This type of file is best suited when we have to access all the records in sequence one after the other. Marks processing of a class is an example.

Random Access File: In this mode of access, a record is accessed using an index maintained for this purpose. It is like browsing through a chapter and within the chapter a page of interest using the index provided at the beginning of the book.

Direct Access File: In this mode, the records are stored based on their relative position with respect to the first record. For example, record 50 will be 50 lengths away from the address of record 1. The main advantage of this mode of access is that there is no need to maintain indexes that would result in memory overhead. The disadvantage is that memory locations get blocked.

C++ language supports both sequential and direct access mode.

Files can be further classified as text files or binary files. Normally, in a text file, data is stored using ASCII character code. Thus, to store 1234.5 in text mode, we would need 6 character spaces, i.e. 48 bits, whereas if you store it in binary mode, one would save a lot of memory as we will convert 1234.5 into binary and then store. Hence, for storing intrinsic data of large numbers and sizes, binary mode is always preferred.

The classes required in connection with file handling in C++ are all kept in fstream header. Therefore, insert a statement : #include<fstream>

To open a file for writing data on to it, we would create an object of ofstream like this:

        ofstream outfile(“Student.dat”);

To open a file for reading data from it, we would create an object of ifstream like this:

        ifstream infile(“Student.dat”);

We need to check if infile stream has been successfully allocated. In C++, logical NOT has been overloaded to check the stream file creation

if(!infile) {cerr<<”
 Sorry cannot open the file infile..”<<endl; exit(1);}

After use, every file that is opened needs to be closed like this outfile.close(); infile.close();

13.6.2 Stream Operating Modes

It is possible to control the stream files opening modes. We need to include these mode switches while creating the object through constructors.

 

ios::app ; appends data to the file at the end of file.
ios::ate : opens the file and positions the reader or writer controller at the read head at the end
ios::in : opens the file for reading
ios::out : opens the file for writing
ios::nocreate : fails to open if it does not exist already
ios::noreplace : file should exist and also either of ios::ate or ios::app should be set.
ios::trunk : truncates the file, if it already exists

We will write a program to copy a file's contents onto another file . In Example 13.6, we would use command line arguments feature. With commandline argument, you can execute the program from command line prompt C:> iop io2.cpp io2copy.cpp There are three arguments, namely, argv[0] = io2.cpp argv[1] = io2.cpp is the source. argv[2] = io2copy.cpp is the destination file. This feature allows us to execute the program without invoking IDE of Turbo C++ or VC++ directly from the command line prompt.

 

Example 13.6:   io3.cpp Program to Copy a File Through Command Line Arguments

#include<fstream>
#include<iostream>
using namespace std;
void main(int argc , char **argv)
{if ( argc<3)
      {cout<<”
 correct usage of command line argument is : copyfile inputfile
      outputfile..”<<endl; exit(0); }
      // open inputfile and connect it to input stream inputstream
      ifstream inputstream(argv[1]);
      if(!inputstream)
      { cout<<”
 cannot open the input file ..”<<argv[1]<<endl; exit(1); }
      //open the output file and connect it to outputstream
      of stream outputstream(argv[2]);
      if(!outputstream)
      { cout<<”
 cannot open the output file ..”<<argv[2]<<endl; exit(1); }
      // now read from input file and copy to output file
      char ch;
      while ( (inputstream.get(ch)) && outputstream ) outputstream.put(ch);
}

We have shown another version in which we obtain the file names from the user and execute copy source file onto the destination file in the solved example section, Ex 2 at the end of the chapter.

 

Example 13.7:   io5.cpp Open a File in Append Mode, Append a Line

#include<fstream>
#include<iostream>
using namespace std;
void main()
{   char filename[30];
    char text[80]; // for user input
    cout <<”
 Enter source file name..: “;
    cin>>filename;
    //Now lets open the file once again for append mode
    ofstream outfile(filename,ios::app);
    if(!outfile)
    { cout<<”
 cannot open the input file for appending..”<<filename <<endl;
    exit(1); }
    cout<<”
 Enter text for inputting to file …”<<endl; cin.ignore(1,’
’);
    cin.getline(text,80); outfile<<text<<”
”;outfile.close();
    cout<<”
 completed writing to output file”<<endl;
    // now lets read the file, we have just outputted our text for confirmation
    cout<<filename<<endl;
    ifstream infile(filename);
    if(!infile)
    {cout<<”
 cannot open the input file ..”<<filename<<endl; exit(1);}
    char ch;
    while ( infile.get(ch)) // now read from input file and copy to output file
    cout<<ch;
    cout<<”
 display process completed..”<<endl;
    infile.close();
}
/*Output:
Enter source file name..: io4.cpp : Enter text for inputting to file …
Hi we are trying out appending through io5.cpp : completed writing to output file
Hi we are trying out appending through io5.cpp : display process completed..*/
Note that C++ supports all form of input and output statements of C language. You can freely use them in C++. We have used the following statements in the program
   char text[30]; // buffer for user input
   cin.getline(text,30); // getline takes in to buffer text maximum of 30 characters
   // But new line character 
 is ignored and not taken in
   cin.ignor(1,’
’); // ignores 1 character shown as second argument

13.7 Binary File

Normally, to facilitate direct reading on the console, the files are stored in text format. But for efficiency and saving the memory space, it would be far more efficient to store the data in binary form, i.e. in 0 s and 1 s. For example, a number 50595 is stored by text file as ‘5’, ‘0’, ‘5’, ‘9’, ‘5’, whereas the binary form will allocate 2 or 4 bytes depending on the hardware used and stores the number as binary equivalent >. In C++ a flag called ios::binary will specify the mode.

A binary file can be used to store all the intrinsic data types as well as user-defined data types like objects. We will use write() to write data on to binary files and read() to get the data from binary files.

Student std ( 20 , 70) ; // student object with roll number and average marks
fileobject.write( ( char*) & std , sizeof (std) );
fileobject.read( ( char*) & std , sizeof (std) );

 

Example 13.8:   io6.cpp Program to Write a Class Called Student on to a File and Read Back the Contents of the File

#include<iostream>
#include<fstream>
using namespace std;
//declare a class called Student
class Student
{ public: Student(int n, char *p, double d) {rollNo=n,name=p, total =d;}
     ~Student(){}; // Default destructor
     // public access functions
     int GetRollNo() const { return rollNo;}
     void SetRollNo ( int n) { rollNo=n;}
     char * GetName() const { return name;}
     void SetName( char *p) { name=p;}
     double GetTotal() const { return total;}
     void SetTotal ( double d) { total=d;}
private: int rollNo; char *name;double total; // name is a pointer to name
};
void main()
{    char filename[80];
     cout<<”
 Enter file name…:”;
     cin >>filename;
     ofstream outfile(filename,ios::binary); // open in bibnary mode
     if(!outfile) cout<<”
 Cannot open iffile in binary mode..”<<filename<<endl;
           exit(1); }
     Student std(5095,”Thunder”,70.0); // create a student object and write on to file
     cout<<”
 Data of Student we have created..”<<endl;
     cout<<”
 Student roll number : “<<std.GetRollNo()<<endl;
     cout<<”
 Student name : “<<std.GetName()<<endl;
     cout<<”
 Student total : “<<std.GetTotal()<<endl;
     outfile.write( (char*) & std , sizeof std ); outfile.close();
     // now lets open the file and read the content
     ifstream infile(filename,ios::binary);
     if(!infile)
     { cout<<”
 Cannot open infile in binary mode..”<<filename <<endl;
           exit(1); }
     // we will create a dummy std2 and read the data from file on to std2
     Student std2(1,”No Name”,0.0);
     infile.read( (char*) &std2 , sizeof(std2) );
     cout<<”
 Data of Student read from file..”<<endl;
     cout<<”
 Student roll number : “<<std2.GetRollNo()<<endl;
     cout<<”
 Student name : “<<std2.GetName()<<endl;
     cout<<”
 Student total : “<<std2.GetTotal()<<endl;
}
/*Output: Enter file name…:stdbinary: Data of Student we have created..
Student roll number: 5095: Student name: Thunder: Student total: 70
Data of Student read from file..
Student roll number: 5095: Student name: Thunder: Student total: 70*/

13.8 Seekg()/Seekp() and Tellg() and Tellp() Functionality of C++

In C language, you have used, fseek() and ftell() to position the read & write cursor on the file. In C++, we will use seekg() and seekp() for get position and seek position. This is because in C++ the same stream is used for both input and output.

Seekg() alters the get position, i.e. the position from where we can read from a file.

Seekp() alters the position from where we can write.

      infile.seekg(256); // skip 256 bytes and position get cursor at position 217
      outfile.seekp(1024); // position the cursor for writing at byte position 1025

tellg() and tellp() functions on the other hand tell us about the position of read and write during our next read and write operation.

      int pos = infile.tellg() ; // indicates the position of next read operation.
      int pos = infile.tellp() ; // indicates the position of next write operation.

 

Example 13.9:   io7.cpp Program to Write Student Object on to File and Use Seekg()/Tellg()

#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
const int max =3;
//declare a class called Student
class Student
{ public:
  Student(){}
  ~Student(){}; // Default destructor
  // public access functions
  void GetData(void);
  void DisplayData(void);
private: int rollNo; char name[20]; float mat,sci,eng,total,avg;};
void Student::GetData(void)
{ cout<<”
 Enter name : “;cin>>name; cout<<”
 Enter id No : “; 
cin>>rollNo;
  cout<<”
 Enter <Maths , Science and English> Marks :”; cin>>mat>> sci>>eng;
  total = mat+sci+eng; avg=total/3.0; }
void Student::DisplayData(void)
{ cout<<"
 Name :"<<setiosflags(ios::left)<<setw(20)<<name;
  cout<<"
 Total :"<<setprecision(2)<<setw(20)<<setiosflags(ios::fixed)<<total<<endl;
  cout<<"
 Average :"<<setprecision(2)<<setw(20)<<avg<<endl; }
void main()
{ Student std[2]; // two student objects
  char filename[30];
  int ch,pos,p,sz=0;
  cout<<"
 Enter filename…";
  cin>>filename;
  fstream inoutfile;
  inoutfile.open(filename,ios::in|ios::out);
  do{cout<<"
 MENU ";
  cout<<"
 1.Add a record
 2.Display nth record
 3.Exit
";
  cout<<" Enter choice of operation: ";cin>>ch;
  switch(ch)
   {case 1: if (sz>=max)
        { cout<<"
 out of bounds.."<<endl; exit(1); }
      std[sz].GetData();
      inoutfile.write((char*)&std[sz],sizeof(std[sz]));
      sz++; // keep the count
      inoutfile.close();
      break;
    case 2: inoutfile.seekg(0); // go to beginning
      cout<<"
Enter the position of the record to be displayed : ";
      cin>>p;
      if(p>max)
      {cout<<"
Position out of bounds";break; }
      pos = (p-1) * sizeof(std) ;
      inoutfile.seekg(pos);
      inoutfile.read((char*)&std[p-1],sizeof(std[p-1]));
      cout<<"
Details of record "<<p<<endl;
           std[p-1].DisplayData();
           inoutfile.close();
           break;
    case 3: exit(1);
    }//end of switch
    }while( ch>=1 && ch<4);
}//end of main
/*Output: Enter filename…Student.dat :
MENU
1.Add a record 2.Display nth record 3.Exit
Enter choice of operation: 1 Enter name: Ramesh Enter id No: 100
Enter <Maths, Science and English> Marks :90 90 90
MENU Enter choice of operation: 2 enter the position of the record to be displayed: 2
details of record 2: Name: Gautam Total: 294.00 : Average: 98.00 */

13.9 Summary

  1. IO streaming is flow of data from one device to another device. For example, from input device like console to memory or from memory to output device like console.
  2. Input from keyboard and output to console are called standard input and output device.
  3. There are operators like inserters and extractors (<< and >>) provided to work with IO stream objects like cin, cout, cerr to convert into ASCII to intrinsic data for storage and convert back to ASCII for outputting to standard IO devices.
  4. The extractor represented by the “>>” symbol translates data sent by I/O devices in memory representation formats such as integers and floats.
  5. iostream library object cin coupled with the extractor operator >> provides the user translation services and also the processing of special characters such as Carriage Return(CR), Space, Tabs and End of File(EOF).
  6. IO streaming functions make use of buffers to cater to different speeds of IO devices and computer systems. Various flags are set by IO streaming function to inform to the user the status IO streaming.
  7. High-level disk IO also called standard IO/stream IO: Buffer management is done by the compiler/operating system.
  8. Low-level disk IO also called system IO: Buffer management is to be taken care by the programmer.
  9. console IO: All the input and output functions control the way input has to be fed and the way output looks on standard output devices, i.e. screen.
  10. Console IO is further classified ad formatted IO and unformatted IO.
  11. Unformatted I/O is also called low-level I/O. It offers the highest efficiency and throughput amongst all the other I/O mechanisms. Unlike formatted I/O, here input has no automatic whitespace, Tab, carriage return detection and processing, and also data is not formatted – the programmer has to interpret the data.
  12. I/O library in C++ provides a mechanism to test whether a particular I/O operation has succeeded or failed. Each stream object maintains a set of flags which indicates the state of the stream after an I/O operation.
  13. C++ supports istream for input and ostream for output. IO stream library includes four types of predefined streams. cin,cout,cerr,clog
  14. IO manipulators alter the status of streams. For using this feature we need to include the statement: #include<iomanip> in global section.
  15. Flags are the arguments that can be passed to setiosflag and resetiosflags manipulators.
  16. File is a collection of records. Records are a collection of fields. Fields are the smallest units of data. Fields can be basic data types or user-defined or derived data.
  17. Sequential File All records are stored sequentially as they are entered.
  18. Random Access File: In this mode of access, a record is accessed using an index maintained for this purpose.
  19. Direct Access File: In this mode, the records are stored based on their relative position with respect to first record.
  20. Files can be further classified as text files or binary files. Normally, in a text file, data is stored using ASCII character code. In binary files, data is stored just like it is stored in memory. Hence, binary mode saves memory.
  21. The classes required in connection with file handling in C++ are all kept in fstream header. Therefore, insert a statement : #include<fstream>
  22. In C++, logical NOT has been overloaded to check the stream file creation. if(!infile) {cerr<<” Sorry cannot open the file infile..”<<endl; exit(1); }. In C++, a flag called ios::binary will specify the mode.
  23. Stream operating modes are used to control the stream files opening modes. Include these mode switches while creating the object through constructors.
  24. Seekg() alters the get position, i.e. the position from where we can read from a file.
  25. Seekp() alters the position from where we can write.
  26. tellg() and tellp() functions on the other hand tell us about the position of read and write during our next read and write operation.

Exercise Questions

Objective Questions

  1. Which of the following statements are true in respect of unformatted IO?
    1. Input has automatic recognition of white space
    2. Low-level IO
    3. Input finishes with EOF
    4. Lowest efficiency
    1. i
    2. i and ii
    3. i, ii and iii
    4. d) ii, iii and iv
  2. << operator defined in IO Stream is called
    1. Inserter
    2. Extractor
    3. Translator
    4. Shift left
    1. i and iii
    2. i and ii
    3. i, ii and iii
    4. ii, iii and iv
  3. << operator defined in IO Stream is called
    1. Insertor
    2. Extractor
    3. Translator
    4. Shift left
    1. i and iii
    2. i and ii
    3. ii and iii
    4. ii, iii and iv
  4. Which of the following statements are true with respect to high-level disk IO?
    1. Also called standard IO
    2. Buffer management by user
    3. Also called stream IO
    4. Operates on files
    1. i
    2. i, iii and iv
    3. i, ii and iii
    4. ii, iii and iv
  5. Which of the following statements are true with respect to low-level disk IO?
    1. Individual character processing
    2. Buffer management by user
    3. Input has automatic white space recognition
    4. Operates with highest efficiency
    1. i
    2. i, iii and iv
    3. i , ii and iii
    4. i, ii and iv
  6. Which of the following statements are true with respect to read(char* str, int count)? :
    1. Reads count characters from Stream
    2. Appends String Terminator character
    3. It is part of unformatted IO
    4. Returns error if EOF is encountered
    1. i
    2. i, iii and iv
    3. i, ii and iii
    4. ii, iii and iv
  7. setw () setprecision() functions are contained in
    1. <iostream>
    2. <iomanip>
    3. <cstring>
    4. <fstream>
  8. Which of the following statements are true with respect to manipulators?
    1. endl flushes the buffer on to console
    2. Inserts a new line character
    3. ignores white spaces in the buffer
    4. i, ii and iii
    1. i
    2. i and ii
    3. iv
    4. ii and iii
  9. Which of the following statements are true with respect to manipulators?
    1. ios::skipws: skip white spaces in input stream
    2. ios::showpos: shows position
    3. ios::showpoint shows decimal point compulsorily
    4. ios::showbase shows base
    1. ii and iii
    2. i, ii and iii
    3. i and iv
    4. i, iii and iv
  10. Seekg() can work relative to any position in the file     TRUE/FALSE
  11. For reading data from a random access file we use
    1. get()
    2. getline()
    3. readline()
    4. read()
  12. Write() function cannot send to standard output stream cout     TRUE/FALSE

    Short-answer Questions

  13. Define IO stream.
  14. What is a byte stream?
  15. Distinguish formatted and unformatted IO.
  16. What do peek() & ignore() and putback() commands achieve?
  17. What predefined IO streams are contained in IO stream library?
  18. Define the terms file, record and field.
  19. What are binary files? How do they save space in memory?
  20. What is sequential access of a file?
  21. Explain direct access method.

    Long-answer Questions

  22. Classify the IO stream functions.
  23. Explain formatted and unformatted IO functions with examples.
  24. Explain what is stream state and flags used by C++.
  25. Explain IO stream class hierarchy.
  26. Explain IO manipulators available in C++.
  27. What flags can be sent as arguments to setiosflag and resetiosflag functions?
  28. Explain file classification in terms of access of data.
  29. Explain stream operating modes with suitable examples.
  30. Explain Seekg() / seekp() and tellg() and tellp() functionality of C++.

    Assignment Questions

  31. Write a program to merge two files into a third file. Each file holds a specified number of strings.
  32. Write a program to print telephone directory. Use a class called Telephone to hold the data and member functions for telephone directory to create the directory and the file.
  33. Write a program to sort the file that holds a specified number of strings.

Solutions to Objective Questions

  1. d
  2. a
  3. c
  4. b
  5. d
  6. b
  7. b
  8. b
  9. d
  10. True
  11. d
  12. False
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.96.105