Lab Sheet 8
Understanding the Concept of Console and File Input/Output
1. Console Input/Output
For console input/output, the stream class library provides the following classes
istream - for input
ostream - for output
iostream - for input and output.
The classes istream and ostream are inherited from the class ios, and the class iostream is inherited from istream and ostream. For console input/output handling, one should include <iostream> in the program.
Within the console, we can perform unformatted and formatted input/output. For unformatted input/output, stream functions like put(), get(), getline(), write(), read() etc. are used. For formatted input/output, the stream objects cin and cout are used along with ios functions and flags, and manipulators.
The ios functions that can be used for formatting are
width() — sets the minimum field width for the next output
fill() — sets the fill character used when padding
precision() — sets the number of digits after the decimal point
setf() — sets a specific formatting flag
unsetf() — clears a specific formatting flag
flags() — returns or sets the entire format flags state
etc.
However, to use the setf(), unsetf(), and flags() functions, one should know the flags available in the ios class. The input/output formatting can also be done with manipulators. The manipulators equivalent to ios functions and flags are available in the stream library. Some manipulators are non-parameterized, and some are parameterized. To use parameterized manipulators, we should include the header <iomanip>.
Similar to other operator overloading, the stream insertion operator << and stream extraction operator >> can be overloaded as non-member friend functions to handle input and output of user-defined types directly with cin and cout or file streams. The general syntax is
ostream& operator<<(ostream& os, myclass& myobj)
{
//......
return os;
}
istream& operator>>(istream& is, myclass& myobj)
{
//......
return is;
}
2. File Handling
The following classes are used for handling files.
ifstream - for handling input files
ofstream - for handling output files
fstream - for handling input as well as output files.
In all these classes, a file can be opened by passing the filename as the first argument to the constructor.
For example,
ifstream infile("test.txt") opens the file test.txt in the input mode.
The constructors for all these classes are defined as follows:
ifstream(const char *path, int mode=ios::in)
ofstream(const char *path, int mode=ios::out)
fstream(const char *path, int mode=ios::in|ios::out)
where path specifies the file to be opened and mode specifies the mode in which it is opened.
The common file modes are as follows:
ios::in — open for reading
ios::out — open for writing
ios::app — append to end of file
ios::binary — open in binary mode
ios::trunc — truncate file if it exists
For file handling, we should include the header file <fstream>, where classes for file handling are declared.
File opening can also be done explicitly by calling the member function open() of the file stream classes. The open() functions have similar prototypes to the constructors.
After opening, the file contents can be written or read by using the stream operators with the file objects as:
ofstream ofile("test.txt");
ofile<<"C++ lab class";
This statement writes "C++ lab class" in the file "test.txt"
For random file access, the file positioning pointer is to be set to a particular position of the file. This can be done by using the seekg() and seekp() functions of ifstream and ofstream classes, respectively. Similarly, to get the information of where the file access pointer is, we can use the member functions tellg() and tellp(). For example
ifstream infile("myfile.txt",ios::binary);
infile.seekg(5);
//...
int pos=infile.tellg();
3. Reading and Writing a Class Object
The binary input and output functions read() and write() are designed to handle the entire structure of an object (or variable) as a single unit, using the computer's internal representation of data. The function write() stores a class object byte by byte to file without conversion. Similarly, the function read() reads objects (or variables) from a file without conversion.
When using write() and read() to dump an entire object byte-by-byte via pointers, we are performing binary I/O. Without the ios::binary mode, the writing and reading from file operating system specific raw bytes may not be translated correctly, generating incorrect results.
Binary output and input functions take the following form:
ipfile.read(reinterpret_cast<char*>(&obj),sizeof(obj));
opfile.write(reinterpret_cast<char*>(&obj),sizeof(obj));
Example
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
class demofile
{
private:
int a;
int b;
public:
demofile():a(0),b(0){}
demofile(int x,int y){a=x;b=y;}
void display()
{cout<<"a= "<<a<<endl<<"b= "<<b<<endl;}
};
int main()
{
demofile src(10,20);
demofile dst;
fstream file;
file.open("demo.txt",ios::in|ios::out|ios::trunc |ios::binary);
//without ios::trunc or ios::app modes ios::in|ios::out expect file to already exist in that folder
if(!file)
{
cout << "File could not be opened." << endl;
return 1;
}
file.write(reinterpret_cast<char*>(&src),sizeof(src));
file.seekg(0);
file.read(reinterpret_cast<char*>(&dst),sizeof(dst));
dst.display();
file.close();
return 0;
}
Write a program that uses ios flags, functions, and manipulators to generate a formatted bill invoice for a department store. The invoice should demonstrate the use of field width, fill characters, and precision formatting.
Write a program to create a parameterized user-defined manipulator that accepts width, precision, and fill character as arguments and applies all three formatting settings simultaneously.
Write a program to overload stream operators to read a complex number and display the complex number in a+ib format.
Write a program that stores objects representing students (name, student ID, department, and address) to a file in your directory. Finally, retrieve the information from your file and print it in the proper format on your output screen.
Write a program that merges the contents of two distinct text files, file1.txt and file2.txt, into a third file named merged.txt. The program should read line-by-line and write alternating lines from each source file to the destination file. If one file is shorter than the other, append the remaining lines of the longer file to the end. Handle all file opening errors gracefully.
Write a program for transaction processing that writes and reads objects randomly to and from a random access file so that the user can add, update, delete, and display the account information (account-number, last-name, first-name, total-balance).