{"id":213,"date":"2018-07-11T05:04:20","date_gmt":"2018-07-11T05:04:20","guid":{"rendered":"http:\/\/itp1.epgpbooks.inflibnet.ac.in\/?post_type=chapter&#038;p=213"},"modified":"2018-07-13T09:30:38","modified_gmt":"2018-07-13T09:30:38","slug":"binary-files-in-c","status":"publish","type":"chapter","link":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/chapter\/binary-files-in-c\/","title":{"rendered":"Binary Files in C++"},"content":{"raw":"<div>\r\n\r\n<strong>Introduction<\/strong>\r\n\r\n&nbsp;\r\n\r\nAs explained in \u2018File I\/O\u2019 module, files are used for persistent data storage. File I\/O facilitates transfer of data between secondary memory (hard disk) and main memory.\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">In C++, there can be two types of files: Text files and Binary files. Text files are discussed at length including examples in \u2018File I\/O\u2019 module. Our level of comfort lies only with proper ASCII or UNICODE characters, as they are human readable.<\/p>\r\n&nbsp;\r\n\r\nIn this module, we will see working with binary files in detail.\r\n\r\n&nbsp;\r\n\r\n<strong>Binary File<\/strong>\r\n\r\n&nbsp;\r\n\r\nBinary file is a file with data stored in raw format, the way it is stored in memory.\r\n\r\n&nbsp;\r\n\r\nFor example, numbers are stored in binary in memory. They are not converted to text (ASCII characters) when writing to binary file.\r\n\r\n&nbsp;\r\n\r\nThe data in binary format is not human readable and cannot be read or modified using text editors.\r\n\r\n&nbsp;\r\n\r\nAdvantages of using binary file over text file\r\n\r\n&nbsp;\r\n\r\nText files perform formatted I\/O; whereas binary files perform unformatted I\/O with raw data. Thus conversion between binary format and ASCII text format do not take place in case of binary files.\r\n\r\n&nbsp;\r\n\r\nSee following example to understand this.\r\n\r\n&nbsp;\r\n\r\nConsider integer value 65536. When read from keyboard, it is entered using keys \u20186\u2019, \u20185\u2019, \u20185\u2019, \u20183\u2019, \u20186\u2019 as ASCII characters. But in memory, data is stored in binary format as 0x\u20190001FFFF\u2019.\r\n\r\n&nbsp;\r\n\r\nInteger 65536 stored as text (using 5 ASCII characters):\r\n\r\n&nbsp;\r\n<table class=\"aligncenter\" border=\"1\">\r\n<tbody>\r\n<tr>\r\n<td style=\"width: 141.063px\">Character<\/td>\r\n<td style=\"width: 92.0625px\">\u20186\u2019<\/td>\r\n<td style=\"width: 92.0625px\">\u20185\u2019<\/td>\r\n<td style=\"width: 93.0625px\">\u20185\u2019<\/td>\r\n<td style=\"width: 93.0625px\">\u20183\u2019<\/td>\r\n<td style=\"width: 93.0625px\">\u20186\u2019<\/td>\r\n<\/tr>\r\n<tr>\r\n<td style=\"width: 141.063px\">ASCII in Binary<\/td>\r\n<td style=\"width: 92.0625px\">00000110<\/td>\r\n<td style=\"width: 92.0625px\">00000101<\/td>\r\n<td style=\"width: 93.0625px\">00000101<\/td>\r\n<td style=\"width: 93.0625px\">00000011<\/td>\r\n<td style=\"width: 93.0625px\">00000110<\/td>\r\n<\/tr>\r\n<tr>\r\n<td style=\"width: 141.063px\">ASCII in Hexa<\/td>\r\n<td style=\"width: 92.0625px\">06<\/td>\r\n<td style=\"width: 92.0625px\">05<\/td>\r\n<td style=\"width: 93.0625px\">05<\/td>\r\n<td style=\"width: 93.0625px\">03<\/td>\r\n<td style=\"width: 93.0625px\">06<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\nInteger 65536 stored as binary in memory (assuming long int, using 4 bytes):\r\n\r\n&nbsp;\r\n<table class=\"aligncenter\" border=\"1\">\r\n<tbody>\r\n<tr>\r\n<td style=\"width: 131.063px\">In Binary<\/td>\r\n<td style=\"width: 152.063px\">00000000<\/td>\r\n<td style=\"width: 145.063px\">00000001<\/td>\r\n<td style=\"width: 95.0625px\">11111111<\/td>\r\n<td style=\"width: 95.0625px\">11111111<\/td>\r\n<\/tr>\r\n<tr>\r\n<td style=\"width: 131.063px\">In Hexa<\/td>\r\n<td style=\"width: 152.063px\">00<\/td>\r\n<td style=\"width: 145.063px\">01<\/td>\r\n<td style=\"width: 95.0625px\">FF<\/td>\r\n<td style=\"width: 95.0625px\">FF<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\nWhen writing the output on screen, it requires converting data stored in memory to text.\r\n\r\nThus, 0x\u20190001FFFF\u2019 is converted to 5 characters \u20186\u2019, \u20185\u2019, \u20185\u2019, \u20183\u2019, \u20186\u2019.\r\n\r\n&nbsp;\r\n\r\nThus, working with text files requires conversion from binary to text or vice versa.\r\n\r\n&nbsp;\r\n\r\nWhen data is stored in binary file, it does not require such conversion. Integer 65536 is stored as 0x\u20190001FFFF\u2019 using 4 bytes without any conversion.\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>Binary read\/write is faster, as data interpretation or conversion is not required<\/li>\r\n \t<li>Binary file uses fixed size of memory space for specific type of objects<\/li>\r\n<\/ul>\r\nIn text file, number 65536 requires 5 ASCII characters (5 bytes), number 123456789 requires 9 bytes and number 2 requires 1 byte of storage space. In case of binary files, all these numbers requires fixed 4 bytes space, assuming long int data type.\r\n\r\n&nbsp;\r\n\r\nFor larger numbers, binary file uses less space as compared to text files.\r\n<ul>\r\n \t<li>Binary file helps in protecting data up to some extent<\/li>\r\n<\/ul>\r\n<p style=\"text-align: justify\">The data stored in binary format is not easy to read for humans. Someone may consider this as a drawback, but it helps in protecting data up to some extent. Text files can be easily edited using simple text editors. Binary files cannot be read using text editors.<\/p>\r\n&nbsp;\r\n\r\nIf information such as marks of students or balance in bank account is stored in text files, it can be easily tampered by someone having access rights. If such information is stored in binary files, data cannot be edited using simple text editors.\r\n\r\n&nbsp;\r\n\r\nAs explained above, binary files are more efficient in terms of speed and memory usage.\r\n\r\nMoreover they provide data protection up to certain level.\r\n\r\n&nbsp;\r\n\r\nWhen to use binary files?\r\n\r\n&nbsp;\r\n\r\nEven though most of the programs usually use ASCII text files, there are certain occasions where binary files will be very useful.\r\n\r\n&nbsp;\r\n\r\nBinary files should be preferred in applications like\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>Number crunching scientific applications requiring large amount of data to be processed<\/li>\r\n \t<li>Data sensitive applications involving financial data, personal data or scores in exam etc.<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\n<strong>Working with binary files<\/strong>\r\n\r\n&nbsp;\r\n\r\nWorking with files in C++ requires the use of file-oriented streams based on classes:\r\n\r\nifstream, ofstream and fstream.\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>ifstream (input file stream) for reading only<\/li>\r\n \t<li>ofstream (output file stream) for writing only<\/li>\r\n \t<li>fstream (file stream) for reading as well as writing<\/li>\r\n<\/ul>\r\nAll these classes are defined in fstream file. Thus, to perform file operations in C++, header files &lt;iostream&gt; and &lt;fstream&gt; must be included in a program.\r\n\r\n&nbsp;\r\n\r\nLike text files, working with binary files also requires following operations:\r\n<ul>\r\n \t<li>open file<\/li>\r\n \t<li>process: read\/write using file, check errors<\/li>\r\n \t<li>close file<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\nBefore any operation can take place on a file, it must be opened first. When working with file is finished, it should be closed to avoid loss of data.\r\n\r\n&nbsp;\r\n\r\nOpening binary file requires open mode ios::binary to be specified. Binary input\/output operations can be performed using read() and write() methods.\r\n\r\n&nbsp;\r\n\r\nPerforming error checks is similar to those in text files.\r\n\r\n&nbsp;\r\n\r\n<strong>Opening Binary file<\/strong>\r\n\r\n&nbsp;\r\n\r\nOpening binary file is similar to opening text files, but requires specifying ios::binary as additional open mode. A file stream object can be opened in one of two ways.\r\n\r\n&nbsp;\r\n\r\nFirst, supply a file name along with an i\/o mode parameter to the constructor when declaring an object:\r\n\r\n&nbsp;\r\n\r\nSyntax: FileStream FileObject (const char *filename[, int mode][, int prot]);\r\n\r\n&nbsp;\r\n\r\nEx. ifstream myFile (\"data.bin\", ios::in | ios::binary);\r\n\r\n&nbsp;\r\n\r\nSecond, call open method after declaring a file stream object.\r\n\r\n&nbsp;\r\n\r\nSyntax of open(): void open(const char *filename[, int mode][, int prot]);\r\n\r\n&nbsp;\r\n\r\nEx. ofstream myFile; \u2026 myFile.open (\"data2.bin\", ios::out | ios::binary);\r\n\r\n&nbsp;\r\n\r\nEx. fstream myFile (\"data.bin\", ios::in | ios::out | ios::binary);\r\n\r\n&nbsp;\r\n\r\nEither approach will work equally well with ifstream, ofstream or fstream object. In the syntax given here, [] indicates that the mode and prot arguments are optional. Default mode is ios::in for ifstream, ios::out for ofstream and ios::in | ios::out for fstream.\r\n\r\n&nbsp;\r\n\r\nFor binary I\/O, opening with mode flag ios::binary indicate to suppress formatting and conversion.\r\n\r\n&nbsp;\r\n\r\n<strong>Note<\/strong>: When working with text files, one may omit the second parameter (the i\/o mode parameter) to use the default mode. However, in order to manipulate binary files, it is necessary to specify the i\/o mode also along with ios::binary mode.\r\n\r\n<\/div>\r\nManipulating binary file\r\n\r\n&nbsp;\r\n\r\nAs binary format does not require type conversion and formatting, conventional text-oriented &lt;&lt; and &gt;&gt; operators are not used normally with binary files.\r\n\r\n&nbsp;\r\n\r\nFile streams include member functions read() and write() specifically designed to read and write binary data.\r\n\r\n&nbsp;\r\n\r\nOne may use methods get() and put() to read\/write single character in binary. But, for binary i\/o of numbers and other complex data types like struct or class, it requires using methods read() and write().\r\n\r\n&nbsp;\r\n\r\nFunction write() is a member function of ostream (inherited by ofstream); and read() is a member function of istream (inherited by ifstream). Objects of class fstream have both these member functions available as fstream is derived from ifstrem and ofstream.\r\n\r\n&nbsp;\r\n\r\nSyntax:\r\n\r\n&nbsp;\r\n\r\nistream&amp; istream::read(char* buf, int size)\r\n\r\n&nbsp;\r\n\r\nostream&amp; ostream::write(const char* buf, int size)\r\n\r\n&nbsp;\r\n\r\nAs seen in the syntax, both read() and write() have same parameters.\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">Parameter buf is of type char * (pointer to char) and it specifies the starting address of an array of bytes where the read data elements are to be stored or from where the data elements are to be written. Note that first parameter should be a C-type array of characters and not a string type of C++.<\/p>\r\n&nbsp;\r\n\r\nThe size parameter specifies the number of characters to be read or written from\/to file.\r\n\r\n&nbsp;\r\n\r\n<strong>1.1.\u00a0 Writing data to binary file<\/strong>\r\n\r\n&nbsp;\r\n\r\nMethod write() can be used to write data to binary file associated with ofstrem or fstrem object.\r\n\r\n&nbsp;\r\n\r\nThe write() method causes specified size of bytes to be written from the given memory location buf to binary file on given stream and moves the file pointer size bytes ahead.\r\n\r\n&nbsp;\r\n\r\nFollowing example writes two numbers in file. First is of type int, and second is of type double. Note that it requires typecasting to (char *) as per syntax. To know the size of an item to be written, one may use sizeof() operator.\r\n\r\n&nbsp;\r\n\r\nExample code segment:\r\n\r\n&nbsp;\r\n\r\nint i = 1234;\r\n\r\n&nbsp;\r\n\r\ndouble d = 12.34;\r\n\r\nofstream fout(\u201cdata.bin\u201d, ios::out | ios::binary);\r\n\r\nfout.write((char *)&amp;i, sizeof(int));\r\n\r\nfout.write((char *)&amp;d, sizeof(double));\r\n<ul>\r\n \t<li>Writing in a file starts at the position of the \"put\" pointer.<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\nIf the put pointer is current at the end of the file, the file is extended. If the put pointer points into the middle of the file, characters in the file are overwritten with the new data.\r\n\r\n&nbsp;\r\n\r\nThe position of the \u201cput\u201d pointer can be known using tellp() method and can be changed using seekp() method.\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>The bytes that are written are not interpreted or formatted.<\/li>\r\n \t<li>The write() method do not add carriage return after writing the data.<\/li>\r\n \t<li>The write method does not assume a null terminator at the end of the bytes in buf being written.<\/li>\r\n<\/ul>\r\n<p style=\"text-align: justify\">It writes size bytes from starting address specified in buf irrespective of occurrence of null character. Null terminator may not be there or may be there before size number of bytes, it has no effect.<\/p>\r\n&nbsp;\r\n<ul>\r\n \t<li style=\"text-align: justify\">If an error occurs while writing (for example, out of disk space), the stream is placed in an error state. Such errors are not common and are often not checked, but it is programmer\u2019s responsibility to check such errors. Once error state bit is set, it remains in effect in following file operations. So, programmer should remember to clear the error state of the file stream before next operation. Error state can be reset using clear() method.<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\n<strong>Note: <\/strong>The data written to a binary file using write( ) can be read accurately using read( ) only.\r\n\r\n&nbsp;\r\n\r\n<strong>1.2.\u00a0 Reading data from binary file<\/strong>\r\n\r\n&nbsp;\r\n\r\nUse read() method to read from a binary file associated with fstream or ifstream object.\r\n\r\n&nbsp;\r\n\r\nFunction read() extracts a given number of bytes from the specified stream and store it into the memory pointed to by the first parameter which is a C-type array of characters.\r\n\r\n&nbsp;\r\n\r\nFollowing example reads two numbers (int and double) from binary file. Note typecasting (char *) used to convert address of int or double to pointer to char.\r\n\r\n&nbsp;\r\n\r\nExample code segment:\r\n\r\n&nbsp;\r\n\r\nint i;\r\n\r\n&nbsp;\r\n\r\ndouble d;\r\n\r\nifstream fin(\u201cdata.bin\u201d, ios::in | ios::binary);\r\n\r\n&nbsp;\r\n\r\nfin.read((char *)&amp;i, sizeof(int));\r\n\r\nfin.read((char *)&amp;d, sizeof(double));\r\n\r\nWhen reading data from a file, there are a couple of things to watch out.\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>It is the responsibility of the programmer to ensure that the buffer is created and is large enough to hold the number of bytes of the data that is being read.<\/li>\r\n<\/ul>\r\nThe following code segment may probably result in a crash. Reading 7 bytes at memory location of x may overwrite next locations after 2 or 4 bytes (depending on size of int).\r\n\r\n&nbsp;\r\n\r\nint x;\r\n\r\n&nbsp;\r\n\r\nifstream infile<strong>;<\/strong>\r\n\r\n&nbsp;\r\n\r\ninfile.open(\"data.bin\", ios::binary | ios::in);\r\n\r\n&nbsp;\r\n\r\ninfile.read((char *) &amp;x, 7); \/\/ reads 7 bytes into a cell that is either 2 or 4 bytes long\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>The bytes that are read are not interpreted, simply stored in memory as read from file.<\/li>\r\n \t<li>The method does not assume anything about line endings.<\/li>\r\n<\/ul>\r\nMethod reads exactly size number of bytes. If end of line happens to occur before size bytes, it has no effect.\r\n<ul>\r\n \t<li>The read method does not place a null terminator at the end of the bytes that are read in.<\/li>\r\n \t<li>If an error occurs while reading (for example, reading after the end of a file), the stream is placed in an error state. In such case, one can use the gcount() method to find out the number of characters actually read.<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\nOnce a stream goes into an error state, all future read operations will fail. Do not forget to use the clear() method to reset the stream to a usable state.\r\n\r\n&nbsp;\r\n\r\n<strong>Checking error in <\/strong>file<strong> operation<\/strong>\r\n\r\n&nbsp;\r\n\r\nIn C++, no file operations cause the program to stop. If an error occurs and is not checked, then the program will be running unreliably. Programmer is responsible to check i\/o errors and do the needful.\r\n\r\n&nbsp;\r\n\r\nTesting for errors, either check error state bits or use methods like good(), fail() etc.\r\n\r\n&nbsp;\r\n\r\nA special method is_open() can be used to check whether opening file is successful or not. Method is_open() returns true if open is successful\r\n\r\n&nbsp;\r\n\r\nFor all other i\/o operations, error can be checked using one of the following:\r\n<ul>\r\n \t<li>Method good() returns true if operation is successful. None of the bits\/flags is set in error state.<\/li>\r\n \t<li>Method fail() returns true when operation is unsuccessful, i.e. if failbit or badbit is set.<\/li>\r\n \t<li>Method bad() returns true when operation is unsuccessful, i.e. if badbit is set.<\/li>\r\n \t<li>Method eof() returns true when end of file is reached, i.e. if eofbit is set.<\/li>\r\n \t<li>Operator ! returns true when operation is unsuccessful, like fail()<\/li>\r\n \t<li>Stream pointer is null when operation is unsuccessful Examples:<\/li>\r\n \t<li>if (fobj.is_open()) {\/\/file opened, process} else {\/\/error}<\/li>\r\n \t<li>if (fobj.good()) {\/\/successful operation, process} else {\/\/error}<\/li>\r\n \t<li>If (fobj.fail()) {\/\/error} else {\/\/ successful operation, process}<\/li>\r\n \t<li>If (fobj.bad()) {\/\/error} else {\/\/ successful operation, process}<\/li>\r\n \t<li>If (fobj.eof()) {\/\/error, end of file} else {\/\/ process}<\/li>\r\n \t<li>If (!fobj) {\/\/error} else {\/\/ successful operation, process}<\/li>\r\n \t<li>if (fobj) {\/\/ successful operation, process} else {\/\/error}<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\nRemember that once error bit of error state is set, it remains in effect. When checking error in next operation with associated stream, it will show an error even if next operation is successful. So, do not forget to reset the error state flag associated with the stream after an error is encountered. One may use clear() method to reset the error state associated with stream.\r\n\r\n&nbsp;\r\n\r\nExamples of working with binary files\r\n\r\n&nbsp;\r\n\r\n<strong>1.3.\u00a0 <\/strong>Program to copy contents of one file to another file using get() and put() methods\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>\/\/ copy one file to another using get(), put()<\/li>\r\n \t<li>\/\/ character by character copy<\/li>\r\n<\/ul>\r\n#include &lt;iostream&gt;\r\n\r\n#include&lt;fstream&gt;\r\n\r\nusing namespace std;\r\n\r\n&nbsp;\r\n\r\nint main()\r\n\r\n{\r\n\r\nifstream fin;\r\n\r\nfin.open(\"file1.pdf\", ios::in | ios::binary);\r\n\r\n&nbsp;\r\n\r\nofstream fout;\r\n\r\nfout.open(\"file2.pdf\", ios::out | ios::binary);\r\n\r\nif (! (fin.is_open() &amp;&amp; fout.is_open()))\r\n\r\n{ cout &lt;&lt; \"Error opening file\u2026\", exit(1); }\r\n\r\n&nbsp;\r\n\r\nchar ch;\r\n\r\nwhile(!fin.eof())\r\n\r\n{ ch = fin.get(); fout.put(ch); }\r\n\r\n&nbsp;\r\n\r\nfin.close();\u00a0\u00a0\u00a0 fout.close();\r\n\r\nreturn 0;\r\n\r\n}\r\n\r\nBefore executing this code, see that the location of input file is same as that of the executable program. Otherwise, use full path.\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n<strong>1.4. <\/strong>Program to copy entire content of one file at a time to another file using read() and write()\r\n\r\n&nbsp;\r\n\r\nIf a file is small enough to get accommodated in memory, binary copy can be performed by reading and writing entire file at a time using single read and write operation.\r\n\r\n&nbsp;\r\n\r\nIn program code 9.1, do modifications as shown below and then execute.\r\n<ul>\r\n \t<li>replace statement<\/li>\r\n<\/ul>\r\nfin.open(\"file1.pdf\", ios::in | ios::binary); with\r\n\r\n&nbsp;\r\n\r\nfin.open(\"file1.pdf\", ios::in | ios::binary | ios::ate); \/\/ file pointer at end of file\r\n<ul>\r\n \t<li>replace code<\/li>\r\n<\/ul>\r\nchar ch;\r\n\r\nwhile(!fin.eof())\r\n\r\n{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ch = fin.get(); fout.put(ch);\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\nwith following code\r\n\r\n&nbsp;\r\n\r\nstreampos size;\r\n\r\nchar * buf;\r\n\r\n&nbsp;\r\n\r\nsize=fin.tellg(); buf=new char [size]; \/\/ get size of file and allocate memory of size bytes\r\n\r\nif (buf) \/\/ memory allocation successful\r\n\r\n{\r\n\r\n&nbsp;\r\n\r\nfin.seekg (0, ios::beg); \/\/ pointer at beginning of file fin.read (buf, size); fout.write (buf, size);\r\n\r\n}\r\n\r\nelse {cout &lt;&lt; \"error allocating memory\";}\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\nHere, input file is opened with ios::ate mode to have file pointer at end. It enables to know the size of file using tellg(); and then memory buffer of that size can be allocated.\r\n\r\n&nbsp;\r\n\r\nNote that the program code size has become larger, but execution will be faster. After all, execution time matters a lot!\r\n\r\n&nbsp;\r\n\r\n<strong>1.5. <\/strong>Program to copy one file to another file with one block at a time using read() and write()\r\n\r\nIf a file is very large, it may not possible to get enough memory to allocate. It is safer to copy block by block. Block size should be selected to be large enough to reduce number of read\/write operations, but to get successful memory allocation.\r\n\r\n&nbsp;\r\n\r\nModify program code 9.1 as follows:\r\n\r\n&nbsp;\r\n\r\nreplace code\r\n\r\n&nbsp;\r\n\r\nchar ch;\r\n\r\nwhile(!fin.eof())\r\n\r\n{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ch = fin.get(); fout.put(ch);\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\nwith following code\r\n\r\n&nbsp;\r\n\r\n\/\/copy block by block\r\n\r\nstreampos size = 4096;\r\n\r\nchar buf [4096];\r\n\r\nwhile (!fin.eof())\r\n\r\n&nbsp;\r\n\r\n{ fin.read (buf, size); fout.write (buf, fin.gcount());\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\n<strong>1.6.\u00a0 <\/strong>Program to write and read objects in binary file using write() and read() methods\r\n\r\n&nbsp;\r\n\r\nFor examples of objects in binary file, consider class Student as shown below:\r\n\r\n&nbsp;\r\n\r\nclass Student\r\n\r\n{char name[30];\r\n\r\nint marks[7]; \/\/ marks in 7 subjects\r\n\r\npublic:\r\n\r\nvoid GetStudentData()\u00a0 \/\/ input student data\r\n\r\n{\r\n\r\ncout &lt;&lt; \"Enter student's name: \";\r\n\r\ncin.getline(name,30);\r\n\r\ncout &lt;&lt; \"Enter marks in 7 subjects:\";\r\n\r\nfor (int i=0; i&lt;7; i++) cin &gt;&gt; marks[i];\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\nvoid ShowStudentData() \/\/ display student data\r\n\r\n{\r\n\r\n&nbsp;\r\n\r\ncout &lt;&lt; \"Name: \" &lt;&lt; name &lt;&lt;endl;\r\n\r\ncout &lt;&lt; \"Marks: \";\r\n\r\nfor (int i = 0; i&lt;7; i++) cout &lt;&lt; marks[i] &lt;&lt; \"\u00a0 \";\r\n\r\ncout &lt;&lt; endl;\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\nchar * getname() { return name; }\r\n\r\nvoid getMarks ()\r\n\r\n{\r\n\r\ncout &lt;&lt; \"Enter marks in 7 subjects:\";\r\n\r\nfor (int i=0; i&lt;7; i++) cin &gt;&gt; marks[i];\r\n\r\n}\r\n\r\n}; \/\/ end class Student\r\n\r\n&nbsp;\r\n\r\nRefer following code to write objects in binary file, read all objects and display. While\r\n\r\nwriting into file, objects are inserted in file at end, so file is to be opened with ios::app\r\n\r\nmode.\r\n\r\nStudent sobj;\r\n\r\n&nbsp;\r\n\r\nvoid writeStudents()\r\n\r\n{\r\n\r\nofstream outfile;\r\n\r\n&nbsp;\r\n\r\noutfile.open(\"student.dat\", ios::out | ios::binary | ios::app); if (!outfile.is_open())\r\n\r\n{ cout &lt;&lt; \"Error opening input file\u2026\", exit(1); }\r\n\r\n&nbsp;\r\n\r\nint i,n;\r\n\r\n&nbsp;\r\n\r\ncout &lt;&lt; \"How many students to add? \";\r\n\r\ncin &gt;&gt; n;\r\n\r\nfor ( i=0; i&lt;n; i++)\r\n\r\n{\r\n\r\ncin.get(); \/\/ extract enter key\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>\/\/ read student data GetStudentData();<\/li>\r\n \t<li>\/\/ write student data in binary file write ( (char*)&amp;sobj, sizeof(sobj));<\/li>\r\n<\/ul>\r\n}\r\n\r\noutfile.close();\r\n\r\n} \/\/ end addStudents\r\n\r\n&nbsp;\r\n\r\nvoid readStudents()\r\n\r\n&nbsp;\r\n\r\n{\r\n\r\n&nbsp;\r\n\r\nifstream infile(\"student.dat\", ios::in | ios::binary); if (!infile )\r\n\r\n{ cout &lt;&lt; \"Error opening input file\u2026\", exit(2); }\r\n<ul>\r\n \t<li>\/\/ read from binary file<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\ninfile.read( (char*)&amp;sobj, sizeof(sobj));\r\n\r\nwhile (!infile.eof())\r\n\r\n&nbsp;\r\n\r\n{\r\n\r\n\/\/if (infile) \/\/ successful read\r\n\r\nsobj.ShowStudentData();\r\n\r\ninfile.read( (char*)&amp;sobj, sizeof(sobj));\r\n\r\n}\r\n\r\ninfile.close();\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\nint main()\r\n\r\n{\r\n\r\nwriteStudents();\r\n\r\n&nbsp;\r\n\r\nreadStudents();\r\n\r\ncout &lt;&lt;\"Press any key \";\r\n\r\ncin.get(); cin.get();\r\n\r\nreturn 0;\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\nSample output of program is shown below.\r\n\r\n&nbsp;\r\n\r\nHow many students to add? 2\r\n\r\nEnter student's name: Tina\r\n\r\nEnter marks in 7 subjects:45 40 38 47 42 48 39\r\n\r\nEnter student's name: Ali\r\n\r\nEnter marks in 7 subjects:48 43 40 37 36 47 45\r\n\r\nName: Tina\r\n\r\n&nbsp;\r\n\r\nMarks: 45\u00a0 40\u00a0 38\u00a0 47\u00a0 42\u00a0 48\u00a0 39\r\n\r\nName: Ali\r\n\r\nMarks: 48\u00a0 43\u00a0 40\u00a0 37\u00a0 36\u00a0 47\u00a0 45\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n<strong>1.6.1. <\/strong>Modify object stored in binary file\r\n\r\n&nbsp;\r\n\r\nAdd function to modify marks of a specified student and write updated record back in binary file as shown here.\r\n\r\n&nbsp;\r\n\r\nvoid modifyMarks()\r\n\r\n{\r\n\r\n\/\/file for read\/write purpose, so use fstream class\r\n\r\nfstream file(\"student.dat\", ios::in | ios::out | ios::binary);\r\n\r\nif (!file )\r\n\r\n{ cout &lt;&lt; \"Error opening input file\u2026\", exit(3); }\r\n\r\n&nbsp;\r\n\r\nchar name [40];\r\n\r\n&nbsp;\r\n\r\ncout &lt;&lt; \"Enter name of student to modify marks: \"; cin &gt;&gt; name;\r\n\r\n&nbsp;\r\n\r\nfile.read( (char*)&amp;sobj, sizeof(sobj));\r\n\r\nwhile (!file.eof())\r\n\r\n{\r\n\r\nif (strcmp(name, sobj.getname())==0) \/\/ object found\r\n\r\n{\r\n\r\nsobj.getMarks();\r\n\r\n&nbsp;\r\n\r\nlong pos = -1 * sizeof(sobj); \/\/for backward move file.seekp (pos, ios::cur); \/\/back from current file.write ((char*)&amp;sobj, sizeof(sobj));\r\n\r\n&nbsp;\r\n\r\nbreak;\r\n\r\n}\r\n\r\nfile.read( (char*)&amp;sobj, sizeof(sobj)); \/\/read next\r\n\r\n&nbsp;\r\n\r\n}\r\n\r\nfile.close();\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\nCalling modifyMarks() and readstudents() in main function will result in the following output:\r\n\r\n&nbsp;\r\n\r\nEnter name of student to modify marks: Tina\r\n\r\nEnter marks in 7 subjects:45 45 46 46 47 47 40\r\n\r\n&nbsp;\r\n\r\nafter modification ...\r\n\r\nName: Tina\r\n\r\nMarks: 45\u00a0 45\u00a0 46\u00a0 46\u00a0 47\u00a0 47\u00a0 40\r\n\r\nName: Ali\r\n\r\nMarks: 48\u00a0 43\u00a0 40\u00a0 37\u00a0 36\u00a0 47\u00a0 45\r\n\r\n&nbsp;\r\n\r\nHere, observe following points in the code:\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>Use of fstream with input as well as output open mode<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\nTo modify marks of a specified student, it requires reading student, modifying marks if name is matching, and then writing student object back at the same position. Hence, one should use fstream class object for i\/o strem.\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>Positioning \u201cput\u201d pointer at the beginning of record before writing<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\nAfter reading an object, file position is moved sizeof(sobj) bytes ahead. Before writing the updated object back, the position of \u201cput\u201d pointer should be moved sizeof(obj) bytes in backward direction.\r\n\r\n&nbsp;\r\n\r\n<strong>1.6.2.<\/strong>\u00a0\u00a0\u00a0 Delete an object from binary file\r\n\r\n&nbsp;\r\n\r\nDeletion of record from a file can be implemented using logical deletion or physical deletion.\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">For logical deletion of an object, add one data member, say delFlag, in a class to mark the object as deleted. Now deletion is as good as modifying object by setting delFlag to true. A care should be taken while processing, like showing only non-deleted objects.<\/p>\r\n<p style=\"text-align: justify\">With physical deletion, an object record is to be removed from file. Due to sequential nature of streams, remaining records are to be shifted. It requires setting \u201cget\u201d and \u201cput\u201d pointer for all remaining records. The simple solution is to write remaining records in one temporary file and copying temporary file back to original file. This can be performed using following steps:<\/p>\r\n&nbsp;\r\n\r\n(i) Create temporary file\r\n\r\n(ii) Read an object from data file\r\n\r\n(iii) If it matches with the specified object to be deleted, do not write in temporary file; otherwise write in temporary file\r\n\r\n(iv) Repeat steps (ii) and (iii) till end of data file\r\n\r\n(v) Close both files\r\n\r\n(vi) Delete original data file\r\n\r\n(vii) Rename temporary file as original data file\r\n\r\n(viii) rename(\"temp.dat\", \"marks.dat\");\r\n\r\n&nbsp;\r\n\r\nRefer following code using physical deletion of records from binary file.\r\n\r\n&nbsp;\r\n\r\nvoid deleteStudent()\r\n\r\n{\r\n\r\n&nbsp;\r\n\r\nifstream infile(\"student.dat\", ios::in | ios::binary); if (!infile )\r\n\r\n{ cout &lt;&lt; \"Error opening input file\u2026\", exit(2); }\r\n\r\n&nbsp;\r\n\r\nofstream tmpfile;\r\n\r\n&nbsp;\r\n\r\ntmpfile.open(\"temp.dat\", ios::out | ios::binary); \/\/ copy objects in temp file if (!tmpfile.is_open())\r\n\r\n&nbsp;\r\n\r\n{ cout &lt;&lt; \"Error opening input file\u2026\", exit(4); }\r\n\r\n&nbsp;\r\n\r\nchar name [40];\r\n\r\n&nbsp;\r\n\r\ncout &lt;&lt; \"Enter name of student to be deleted: \"; cin &gt;&gt; name;\r\n\r\n&nbsp;\r\n\r\ninfile.read( (char*)&amp;sobj, sizeof(sobj));\r\n\r\nwhile (!infile.eof())\r\n\r\n{\r\n\r\nif (strcmp(name, sobj.getname())!=0) \/\/ object not to be deleted\r\n\r\n{\r\n\r\ntmpfile.write ((char*)&amp;sobj, sizeof(sobj));\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\ninfile.read( (char*)&amp;sobj, sizeof(sobj)); \/\/read next\r\n\r\n}\r\n\r\ninfile.close(); tmpfile.close();\r\n\r\nremove(\"student.dat\"); \/\/ remove old student.date file\r\n\r\n&nbsp;\r\n\r\nrename(\"temp.dat\", \"student.dat\"); \/\/ rename temp.dat to student.dat\r\n\r\n}\r\n\r\nWrite following lines in main() and execute program.\r\n\r\n&nbsp;\r\n\r\ndeleteStudent();\r\n\r\ncout &lt;&lt; \"\\nafter deletion ... \\n\";\r\n\r\n&nbsp;\r\n\r\nreadStudents();\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\nObserve the ouput:\r\n\r\n&nbsp;\r\n\r\nEnter name of student to be deleted: Tina\r\n\r\n&nbsp;\r\n\r\nafter deletion ...\r\n\r\nName: Ali\r\n\r\nMarks: 48\u00a0 43\u00a0 40\u00a0 37\u00a0 36\u00a0 47\u00a0 45\r\n\r\n&nbsp;\r\n\r\n<strong>1.6.3. Random access: Reading nth object from binary file<\/strong>\r\n\r\n&nbsp;\r\n\r\nTo access nth object from file without reading previous records, simply position \u201cget\u201d file pointer at (n-1)*sizeof(obj) bytes from beginning of file and read the record as follows.\r\n\r\n&nbsp;\r\n\r\nifstream file;\r\n\r\nfile.open(\"student.dat\", ios::in | ios::binary);\r\n\r\n\/\/input n\r\n\r\nlong pos = (n-1) * sizeof(sobj); \/\/for moving pos bytes ahead from beginning\r\n\r\nfile.seekg (pos);\u00a0 \/\/ from beginning\r\n\r\nfile.read ((char*)&amp;sobj, sizeof(sobj));\r\n\r\nsobj.ShowStudentData();\r\n\r\nfile.close();\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n<strong>Summary<\/strong>\r\n<ul>\r\n \t<li>Binary files are used for persistent storage of data in raw format o No type conversion or formatting takes place<\/li>\r\n<\/ul>\r\no\u00a0 Data stored in the format as it is stored in main memory\r\n<ul>\r\n \t<li>Advantages of binary files over text files\r\n<ul>\r\n \t<li>o Faster input\/output operations<\/li>\r\n \t<li>o Storage apace efficient<\/li>\r\n \t<li>o Not editable using text editors<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n<ul>\r\n \t<li>While opening, requires ios::binary open mode to be specified alongwith other modes<\/li>\r\n \t<li>Input\/output operations can be performed using\r\n<ul>\r\n \t<li>o Methods read() and write() for any type of data; may be numeric, character,<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n&nbsp;\r\n\r\nstring, struct, object etc.\r\n<ul>\r\n \t<li>o Additionally, methods get() and put() can be used to read and write character data<\/li>\r\n \t<li>Random access and file error handling is same as with text files<\/li>\r\n<\/ul>\r\n<strong>References<\/strong>\r\n\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n1) Stanley Lippmann, \u201cC++ Primer\u201d, Pearson Education.\r\n\r\n2) Bjarne Stroustrup, \u201cThe C++ Programming Language\u201d, Pearson Education.\r\n\r\n3) Scott Mayer, \u201cEffective C++\u201d, Addison Wesley.\r\n\r\n4) Bhushan Trivedi , Programming with ANSI C++, 2\/e , Oxford University Press.\r\n\r\n5) Yashavant P. Kanetkar \u201cLet Us C++\u201d , Bpb Publications.\r\n\r\n6) Abhiram G. Ranade, \u201cAn Introduction to Programming through C++\u201d , McGraw Hill\r\n\r\n7) Ellis and B. Stroustrup \u201cAnnotated C++ Reference Manual\u201d, http:\/\/www.stroustrup.com\/arm.html\r\n\r\n8) Herbert Schildt, \u201cComplete Reference C++\u201d, McGraw Hill Publications.\r\n\r\n9) Ashok Kamthane, \u201cObject Oriented Programming with ANSI and Turbo C++\u201d, Pearson Education\r\n\r\n10) E Balaguruswami, \u201cObject Oriented Programming With C++\u201d, Tata McGraw Hill\r\n\r\n11) \u201cC++ FAQs\u201d, Pearson Education.\r\n\r\n&nbsp;","rendered":"<div>\n<p><strong>Introduction<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>As explained in \u2018File I\/O\u2019 module, files are used for persistent data storage. File I\/O facilitates transfer of data between secondary memory (hard disk) and main memory.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">In C++, there can be two types of files: Text files and Binary files. Text files are discussed at length including examples in \u2018File I\/O\u2019 module. Our level of comfort lies only with proper ASCII or UNICODE characters, as they are human readable.<\/p>\n<p>&nbsp;<\/p>\n<p>In this module, we will see working with binary files in detail.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Binary File<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Binary file is a file with data stored in raw format, the way it is stored in memory.<\/p>\n<p>&nbsp;<\/p>\n<p>For example, numbers are stored in binary in memory. They are not converted to text (ASCII characters) when writing to binary file.<\/p>\n<p>&nbsp;<\/p>\n<p>The data in binary format is not human readable and cannot be read or modified using text editors.<\/p>\n<p>&nbsp;<\/p>\n<p>Advantages of using binary file over text file<\/p>\n<p>&nbsp;<\/p>\n<p>Text files perform formatted I\/O; whereas binary files perform unformatted I\/O with raw data. Thus conversion between binary format and ASCII text format do not take place in case of binary files.<\/p>\n<p>&nbsp;<\/p>\n<p>See following example to understand this.<\/p>\n<p>&nbsp;<\/p>\n<p>Consider integer value 65536. When read from keyboard, it is entered using keys \u20186\u2019, \u20185\u2019, \u20185\u2019, \u20183\u2019, \u20186\u2019 as ASCII characters. But in memory, data is stored in binary format as 0x\u20190001FFFF\u2019.<\/p>\n<p>&nbsp;<\/p>\n<p>Integer 65536 stored as text (using 5 ASCII characters):<\/p>\n<p>&nbsp;<\/p>\n<table class=\"aligncenter\">\n<tbody>\n<tr>\n<td style=\"width: 141.063px\">Character<\/td>\n<td style=\"width: 92.0625px\">\u20186\u2019<\/td>\n<td style=\"width: 92.0625px\">\u20185\u2019<\/td>\n<td style=\"width: 93.0625px\">\u20185\u2019<\/td>\n<td style=\"width: 93.0625px\">\u20183\u2019<\/td>\n<td style=\"width: 93.0625px\">\u20186\u2019<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 141.063px\">ASCII in Binary<\/td>\n<td style=\"width: 92.0625px\">00000110<\/td>\n<td style=\"width: 92.0625px\">00000101<\/td>\n<td style=\"width: 93.0625px\">00000101<\/td>\n<td style=\"width: 93.0625px\">00000011<\/td>\n<td style=\"width: 93.0625px\">00000110<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 141.063px\">ASCII in Hexa<\/td>\n<td style=\"width: 92.0625px\">06<\/td>\n<td style=\"width: 92.0625px\">05<\/td>\n<td style=\"width: 93.0625px\">05<\/td>\n<td style=\"width: 93.0625px\">03<\/td>\n<td style=\"width: 93.0625px\">06<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Integer 65536 stored as binary in memory (assuming long int, using 4 bytes):<\/p>\n<p>&nbsp;<\/p>\n<table class=\"aligncenter\">\n<tbody>\n<tr>\n<td style=\"width: 131.063px\">In Binary<\/td>\n<td style=\"width: 152.063px\">00000000<\/td>\n<td style=\"width: 145.063px\">00000001<\/td>\n<td style=\"width: 95.0625px\">11111111<\/td>\n<td style=\"width: 95.0625px\">11111111<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 131.063px\">In Hexa<\/td>\n<td style=\"width: 152.063px\">00<\/td>\n<td style=\"width: 145.063px\">01<\/td>\n<td style=\"width: 95.0625px\">FF<\/td>\n<td style=\"width: 95.0625px\">FF<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>When writing the output on screen, it requires converting data stored in memory to text.<\/p>\n<p>Thus, 0x\u20190001FFFF\u2019 is converted to 5 characters \u20186\u2019, \u20185\u2019, \u20185\u2019, \u20183\u2019, \u20186\u2019.<\/p>\n<p>&nbsp;<\/p>\n<p>Thus, working with text files requires conversion from binary to text or vice versa.<\/p>\n<p>&nbsp;<\/p>\n<p>When data is stored in binary file, it does not require such conversion. Integer 65536 is stored as 0x\u20190001FFFF\u2019 using 4 bytes without any conversion.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Binary read\/write is faster, as data interpretation or conversion is not required<\/li>\n<li>Binary file uses fixed size of memory space for specific type of objects<\/li>\n<\/ul>\n<p>In text file, number 65536 requires 5 ASCII characters (5 bytes), number 123456789 requires 9 bytes and number 2 requires 1 byte of storage space. In case of binary files, all these numbers requires fixed 4 bytes space, assuming long int data type.<\/p>\n<p>&nbsp;<\/p>\n<p>For larger numbers, binary file uses less space as compared to text files.<\/p>\n<ul>\n<li>Binary file helps in protecting data up to some extent<\/li>\n<\/ul>\n<p style=\"text-align: justify\">The data stored in binary format is not easy to read for humans. Someone may consider this as a drawback, but it helps in protecting data up to some extent. Text files can be easily edited using simple text editors. Binary files cannot be read using text editors.<\/p>\n<p>&nbsp;<\/p>\n<p>If information such as marks of students or balance in bank account is stored in text files, it can be easily tampered by someone having access rights. If such information is stored in binary files, data cannot be edited using simple text editors.<\/p>\n<p>&nbsp;<\/p>\n<p>As explained above, binary files are more efficient in terms of speed and memory usage.<\/p>\n<p>Moreover they provide data protection up to certain level.<\/p>\n<p>&nbsp;<\/p>\n<p>When to use binary files?<\/p>\n<p>&nbsp;<\/p>\n<p>Even though most of the programs usually use ASCII text files, there are certain occasions where binary files will be very useful.<\/p>\n<p>&nbsp;<\/p>\n<p>Binary files should be preferred in applications like<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Number crunching scientific applications requiring large amount of data to be processed<\/li>\n<li>Data sensitive applications involving financial data, personal data or scores in exam etc.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><strong>Working with binary files<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Working with files in C++ requires the use of file-oriented streams based on classes:<\/p>\n<p>ifstream, ofstream and fstream.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>ifstream (input file stream) for reading only<\/li>\n<li>ofstream (output file stream) for writing only<\/li>\n<li>fstream (file stream) for reading as well as writing<\/li>\n<\/ul>\n<p>All these classes are defined in fstream file. Thus, to perform file operations in C++, header files &lt;iostream&gt; and &lt;fstream&gt; must be included in a program.<\/p>\n<p>&nbsp;<\/p>\n<p>Like text files, working with binary files also requires following operations:<\/p>\n<ul>\n<li>open file<\/li>\n<li>process: read\/write using file, check errors<\/li>\n<li>close file<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Before any operation can take place on a file, it must be opened first. When working with file is finished, it should be closed to avoid loss of data.<\/p>\n<p>&nbsp;<\/p>\n<p>Opening binary file requires open mode ios::binary to be specified. Binary input\/output operations can be performed using read() and write() methods.<\/p>\n<p>&nbsp;<\/p>\n<p>Performing error checks is similar to those in text files.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Opening Binary file<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Opening binary file is similar to opening text files, but requires specifying ios::binary as additional open mode. A file stream object can be opened in one of two ways.<\/p>\n<p>&nbsp;<\/p>\n<p>First, supply a file name along with an i\/o mode parameter to the constructor when declaring an object:<\/p>\n<p>&nbsp;<\/p>\n<p>Syntax: FileStream FileObject (const char *filename[, int mode][, int prot]);<\/p>\n<p>&nbsp;<\/p>\n<p>Ex. ifstream myFile (&#8220;data.bin&#8221;, ios::in | ios::binary);<\/p>\n<p>&nbsp;<\/p>\n<p>Second, call open method after declaring a file stream object.<\/p>\n<p>&nbsp;<\/p>\n<p>Syntax of open(): void open(const char *filename[, int mode][, int prot]);<\/p>\n<p>&nbsp;<\/p>\n<p>Ex. ofstream myFile; \u2026 myFile.open (&#8220;data2.bin&#8221;, ios::out | ios::binary);<\/p>\n<p>&nbsp;<\/p>\n<p>Ex. fstream myFile (&#8220;data.bin&#8221;, ios::in | ios::out | ios::binary);<\/p>\n<p>&nbsp;<\/p>\n<p>Either approach will work equally well with ifstream, ofstream or fstream object. In the syntax given here, [] indicates that the mode and prot arguments are optional. Default mode is ios::in for ifstream, ios::out for ofstream and ios::in | ios::out for fstream.<\/p>\n<p>&nbsp;<\/p>\n<p>For binary I\/O, opening with mode flag ios::binary indicate to suppress formatting and conversion.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Note<\/strong>: When working with text files, one may omit the second parameter (the i\/o mode parameter) to use the default mode. However, in order to manipulate binary files, it is necessary to specify the i\/o mode also along with ios::binary mode.<\/p>\n<\/div>\n<p>Manipulating binary file<\/p>\n<p>&nbsp;<\/p>\n<p>As binary format does not require type conversion and formatting, conventional text-oriented &lt;&lt; and &gt;&gt; operators are not used normally with binary files.<\/p>\n<p>&nbsp;<\/p>\n<p>File streams include member functions read() and write() specifically designed to read and write binary data.<\/p>\n<p>&nbsp;<\/p>\n<p>One may use methods get() and put() to read\/write single character in binary. But, for binary i\/o of numbers and other complex data types like struct or class, it requires using methods read() and write().<\/p>\n<p>&nbsp;<\/p>\n<p>Function write() is a member function of ostream (inherited by ofstream); and read() is a member function of istream (inherited by ifstream). Objects of class fstream have both these member functions available as fstream is derived from ifstrem and ofstream.<\/p>\n<p>&nbsp;<\/p>\n<p>Syntax:<\/p>\n<p>&nbsp;<\/p>\n<p>istream&amp; istream::read(char* buf, int size)<\/p>\n<p>&nbsp;<\/p>\n<p>ostream&amp; ostream::write(const char* buf, int size)<\/p>\n<p>&nbsp;<\/p>\n<p>As seen in the syntax, both read() and write() have same parameters.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Parameter buf is of type char * (pointer to char) and it specifies the starting address of an array of bytes where the read data elements are to be stored or from where the data elements are to be written. Note that first parameter should be a C-type array of characters and not a string type of C++.<\/p>\n<p>&nbsp;<\/p>\n<p>The size parameter specifies the number of characters to be read or written from\/to file.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.1.\u00a0 Writing data to binary file<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Method write() can be used to write data to binary file associated with ofstrem or fstrem object.<\/p>\n<p>&nbsp;<\/p>\n<p>The write() method causes specified size of bytes to be written from the given memory location buf to binary file on given stream and moves the file pointer size bytes ahead.<\/p>\n<p>&nbsp;<\/p>\n<p>Following example writes two numbers in file. First is of type int, and second is of type double. Note that it requires typecasting to (char *) as per syntax. To know the size of an item to be written, one may use sizeof() operator.<\/p>\n<p>&nbsp;<\/p>\n<p>Example code segment:<\/p>\n<p>&nbsp;<\/p>\n<p>int i = 1234;<\/p>\n<p>&nbsp;<\/p>\n<p>double d = 12.34;<\/p>\n<p>ofstream fout(\u201cdata.bin\u201d, ios::out | ios::binary);<\/p>\n<p>fout.write((char *)&amp;i, sizeof(int));<\/p>\n<p>fout.write((char *)&amp;d, sizeof(double));<\/p>\n<ul>\n<li>Writing in a file starts at the position of the &#8220;put&#8221; pointer.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>If the put pointer is current at the end of the file, the file is extended. If the put pointer points into the middle of the file, characters in the file are overwritten with the new data.<\/p>\n<p>&nbsp;<\/p>\n<p>The position of the \u201cput\u201d pointer can be known using tellp() method and can be changed using seekp() method.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>The bytes that are written are not interpreted or formatted.<\/li>\n<li>The write() method do not add carriage return after writing the data.<\/li>\n<li>The write method does not assume a null terminator at the end of the bytes in buf being written.<\/li>\n<\/ul>\n<p style=\"text-align: justify\">It writes size bytes from starting address specified in buf irrespective of occurrence of null character. Null terminator may not be there or may be there before size number of bytes, it has no effect.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"text-align: justify\">If an error occurs while writing (for example, out of disk space), the stream is placed in an error state. Such errors are not common and are often not checked, but it is programmer\u2019s responsibility to check such errors. Once error state bit is set, it remains in effect in following file operations. So, programmer should remember to clear the error state of the file stream before next operation. Error state can be reset using clear() method.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><strong>Note: <\/strong>The data written to a binary file using write( ) can be read accurately using read( ) only.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.2.\u00a0 Reading data from binary file<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Use read() method to read from a binary file associated with fstream or ifstream object.<\/p>\n<p>&nbsp;<\/p>\n<p>Function read() extracts a given number of bytes from the specified stream and store it into the memory pointed to by the first parameter which is a C-type array of characters.<\/p>\n<p>&nbsp;<\/p>\n<p>Following example reads two numbers (int and double) from binary file. Note typecasting (char *) used to convert address of int or double to pointer to char.<\/p>\n<p>&nbsp;<\/p>\n<p>Example code segment:<\/p>\n<p>&nbsp;<\/p>\n<p>int i;<\/p>\n<p>&nbsp;<\/p>\n<p>double d;<\/p>\n<p>ifstream fin(\u201cdata.bin\u201d, ios::in | ios::binary);<\/p>\n<p>&nbsp;<\/p>\n<p>fin.read((char *)&amp;i, sizeof(int));<\/p>\n<p>fin.read((char *)&amp;d, sizeof(double));<\/p>\n<p>When reading data from a file, there are a couple of things to watch out.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>It is the responsibility of the programmer to ensure that the buffer is created and is large enough to hold the number of bytes of the data that is being read.<\/li>\n<\/ul>\n<p>The following code segment may probably result in a crash. Reading 7 bytes at memory location of x may overwrite next locations after 2 or 4 bytes (depending on size of int).<\/p>\n<p>&nbsp;<\/p>\n<p>int x;<\/p>\n<p>&nbsp;<\/p>\n<p>ifstream infile<strong>;<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>infile.open(&#8220;data.bin&#8221;, ios::binary | ios::in);<\/p>\n<p>&nbsp;<\/p>\n<p>infile.read((char *) &amp;x, 7); \/\/ reads 7 bytes into a cell that is either 2 or 4 bytes long<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>The bytes that are read are not interpreted, simply stored in memory as read from file.<\/li>\n<li>The method does not assume anything about line endings.<\/li>\n<\/ul>\n<p>Method reads exactly size number of bytes. If end of line happens to occur before size bytes, it has no effect.<\/p>\n<ul>\n<li>The read method does not place a null terminator at the end of the bytes that are read in.<\/li>\n<li>If an error occurs while reading (for example, reading after the end of a file), the stream is placed in an error state. In such case, one can use the gcount() method to find out the number of characters actually read.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Once a stream goes into an error state, all future read operations will fail. Do not forget to use the clear() method to reset the stream to a usable state.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Checking error in <\/strong>file<strong> operation<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>In C++, no file operations cause the program to stop. If an error occurs and is not checked, then the program will be running unreliably. Programmer is responsible to check i\/o errors and do the needful.<\/p>\n<p>&nbsp;<\/p>\n<p>Testing for errors, either check error state bits or use methods like good(), fail() etc.<\/p>\n<p>&nbsp;<\/p>\n<p>A special method is_open() can be used to check whether opening file is successful or not. Method is_open() returns true if open is successful<\/p>\n<p>&nbsp;<\/p>\n<p>For all other i\/o operations, error can be checked using one of the following:<\/p>\n<ul>\n<li>Method good() returns true if operation is successful. None of the bits\/flags is set in error state.<\/li>\n<li>Method fail() returns true when operation is unsuccessful, i.e. if failbit or badbit is set.<\/li>\n<li>Method bad() returns true when operation is unsuccessful, i.e. if badbit is set.<\/li>\n<li>Method eof() returns true when end of file is reached, i.e. if eofbit is set.<\/li>\n<li>Operator ! returns true when operation is unsuccessful, like fail()<\/li>\n<li>Stream pointer is null when operation is unsuccessful Examples:<\/li>\n<li>if (fobj.is_open()) {\/\/file opened, process} else {\/\/error}<\/li>\n<li>if (fobj.good()) {\/\/successful operation, process} else {\/\/error}<\/li>\n<li>If (fobj.fail()) {\/\/error} else {\/\/ successful operation, process}<\/li>\n<li>If (fobj.bad()) {\/\/error} else {\/\/ successful operation, process}<\/li>\n<li>If (fobj.eof()) {\/\/error, end of file} else {\/\/ process}<\/li>\n<li>If (!fobj) {\/\/error} else {\/\/ successful operation, process}<\/li>\n<li>if (fobj) {\/\/ successful operation, process} else {\/\/error}<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Remember that once error bit of error state is set, it remains in effect. When checking error in next operation with associated stream, it will show an error even if next operation is successful. So, do not forget to reset the error state flag associated with the stream after an error is encountered. One may use clear() method to reset the error state associated with stream.<\/p>\n<p>&nbsp;<\/p>\n<p>Examples of working with binary files<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.3.\u00a0 <\/strong>Program to copy contents of one file to another file using get() and put() methods<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>\/\/ copy one file to another using get(), put()<\/li>\n<li>\/\/ character by character copy<\/li>\n<\/ul>\n<p>#include &lt;iostream&gt;<\/p>\n<p>#include&lt;fstream&gt;<\/p>\n<p>using namespace std;<\/p>\n<p>&nbsp;<\/p>\n<p>int main()<\/p>\n<p>{<\/p>\n<p>ifstream fin;<\/p>\n<p>fin.open(&#8220;file1.pdf&#8221;, ios::in | ios::binary);<\/p>\n<p>&nbsp;<\/p>\n<p>ofstream fout;<\/p>\n<p>fout.open(&#8220;file2.pdf&#8221;, ios::out | ios::binary);<\/p>\n<p>if (! (fin.is_open() &amp;&amp; fout.is_open()))<\/p>\n<p>{ cout &lt;&lt; &#8220;Error opening file\u2026&#8221;, exit(1); }<\/p>\n<p>&nbsp;<\/p>\n<p>char ch;<\/p>\n<p>while(!fin.eof())<\/p>\n<p>{ ch = fin.get(); fout.put(ch); }<\/p>\n<p>&nbsp;<\/p>\n<p>fin.close();\u00a0\u00a0\u00a0 fout.close();<\/p>\n<p>return 0;<\/p>\n<p>}<\/p>\n<p>Before executing this code, see that the location of input file is same as that of the executable program. Otherwise, use full path.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.4. <\/strong>Program to copy entire content of one file at a time to another file using read() and write()<\/p>\n<p>&nbsp;<\/p>\n<p>If a file is small enough to get accommodated in memory, binary copy can be performed by reading and writing entire file at a time using single read and write operation.<\/p>\n<p>&nbsp;<\/p>\n<p>In program code 9.1, do modifications as shown below and then execute.<\/p>\n<ul>\n<li>replace statement<\/li>\n<\/ul>\n<p>fin.open(&#8220;file1.pdf&#8221;, ios::in | ios::binary); with<\/p>\n<p>&nbsp;<\/p>\n<p>fin.open(&#8220;file1.pdf&#8221;, ios::in | ios::binary | ios::ate); \/\/ file pointer at end of file<\/p>\n<ul>\n<li>replace code<\/li>\n<\/ul>\n<p>char ch;<\/p>\n<p>while(!fin.eof())<\/p>\n<p>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ch = fin.get(); fout.put(ch);\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>with following code<\/p>\n<p>&nbsp;<\/p>\n<p>streampos size;<\/p>\n<p>char * buf;<\/p>\n<p>&nbsp;<\/p>\n<p>size=fin.tellg(); buf=new char [size]; \/\/ get size of file and allocate memory of size bytes<\/p>\n<p>if (buf) \/\/ memory allocation successful<\/p>\n<p>{<\/p>\n<p>&nbsp;<\/p>\n<p>fin.seekg (0, ios::beg); \/\/ pointer at beginning of file fin.read (buf, size); fout.write (buf, size);<\/p>\n<p>}<\/p>\n<p>else {cout &lt;&lt; &#8220;error allocating memory&#8221;;}<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Here, input file is opened with ios::ate mode to have file pointer at end. It enables to know the size of file using tellg(); and then memory buffer of that size can be allocated.<\/p>\n<p>&nbsp;<\/p>\n<p>Note that the program code size has become larger, but execution will be faster. After all, execution time matters a lot!<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.5. <\/strong>Program to copy one file to another file with one block at a time using read() and write()<\/p>\n<p>If a file is very large, it may not possible to get enough memory to allocate. It is safer to copy block by block. Block size should be selected to be large enough to reduce number of read\/write operations, but to get successful memory allocation.<\/p>\n<p>&nbsp;<\/p>\n<p>Modify program code 9.1 as follows:<\/p>\n<p>&nbsp;<\/p>\n<p>replace code<\/p>\n<p>&nbsp;<\/p>\n<p>char ch;<\/p>\n<p>while(!fin.eof())<\/p>\n<p>{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ch = fin.get(); fout.put(ch);\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>with following code<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/copy block by block<\/p>\n<p>streampos size = 4096;<\/p>\n<p>char buf [4096];<\/p>\n<p>while (!fin.eof())<\/p>\n<p>&nbsp;<\/p>\n<p>{ fin.read (buf, size); fout.write (buf, fin.gcount());<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.6.\u00a0 <\/strong>Program to write and read objects in binary file using write() and read() methods<\/p>\n<p>&nbsp;<\/p>\n<p>For examples of objects in binary file, consider class Student as shown below:<\/p>\n<p>&nbsp;<\/p>\n<p>class Student<\/p>\n<p>{char name[30];<\/p>\n<p>int marks[7]; \/\/ marks in 7 subjects<\/p>\n<p>public:<\/p>\n<p>void GetStudentData()\u00a0 \/\/ input student data<\/p>\n<p>{<\/p>\n<p>cout &lt;&lt; &#8220;Enter student&#8217;s name: &#8220;;<\/p>\n<p>cin.getline(name,30);<\/p>\n<p>cout &lt;&lt; &#8220;Enter marks in 7 subjects:&#8221;;<\/p>\n<p>for (int i=0; i&lt;7; i++) cin &gt;&gt; marks[i];<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>void ShowStudentData() \/\/ display student data<\/p>\n<p>{<\/p>\n<p>&nbsp;<\/p>\n<p>cout &lt;&lt; &#8220;Name: &#8221; &lt;&lt; name &lt;&lt;endl;<\/p>\n<p>cout &lt;&lt; &#8220;Marks: &#8220;;<\/p>\n<p>for (int i = 0; i&lt;7; i++) cout &lt;&lt; marks[i] &lt;&lt; &#8221;\u00a0 &#8220;;<\/p>\n<p>cout &lt;&lt; endl;<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>char * getname() { return name; }<\/p>\n<p>void getMarks ()<\/p>\n<p>{<\/p>\n<p>cout &lt;&lt; &#8220;Enter marks in 7 subjects:&#8221;;<\/p>\n<p>for (int i=0; i&lt;7; i++) cin &gt;&gt; marks[i];<\/p>\n<p>}<\/p>\n<p>}; \/\/ end class Student<\/p>\n<p>&nbsp;<\/p>\n<p>Refer following code to write objects in binary file, read all objects and display. While<\/p>\n<p>writing into file, objects are inserted in file at end, so file is to be opened with ios::app<\/p>\n<p>mode.<\/p>\n<p>Student sobj;<\/p>\n<p>&nbsp;<\/p>\n<p>void writeStudents()<\/p>\n<p>{<\/p>\n<p>ofstream outfile;<\/p>\n<p>&nbsp;<\/p>\n<p>outfile.open(&#8220;student.dat&#8221;, ios::out | ios::binary | ios::app); if (!outfile.is_open())<\/p>\n<p>{ cout &lt;&lt; &#8220;Error opening input file\u2026&#8221;, exit(1); }<\/p>\n<p>&nbsp;<\/p>\n<p>int i,n;<\/p>\n<p>&nbsp;<\/p>\n<p>cout &lt;&lt; &#8220;How many students to add? &#8220;;<\/p>\n<p>cin &gt;&gt; n;<\/p>\n<p>for ( i=0; i&lt;n; i++)<\/p>\n<p>{<\/p>\n<p>cin.get(); \/\/ extract enter key<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>\/\/ read student data GetStudentData();<\/li>\n<li>\/\/ write student data in binary file write ( (char*)&amp;sobj, sizeof(sobj));<\/li>\n<\/ul>\n<p>}<\/p>\n<p>outfile.close();<\/p>\n<p>} \/\/ end addStudents<\/p>\n<p>&nbsp;<\/p>\n<p>void readStudents()<\/p>\n<p>&nbsp;<\/p>\n<p>{<\/p>\n<p>&nbsp;<\/p>\n<p>ifstream infile(&#8220;student.dat&#8221;, ios::in | ios::binary); if (!infile )<\/p>\n<p>{ cout &lt;&lt; &#8220;Error opening input file\u2026&#8221;, exit(2); }<\/p>\n<ul>\n<li>\/\/ read from binary file<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>infile.read( (char*)&amp;sobj, sizeof(sobj));<\/p>\n<p>while (!infile.eof())<\/p>\n<p>&nbsp;<\/p>\n<p>{<\/p>\n<p>\/\/if (infile) \/\/ successful read<\/p>\n<p>sobj.ShowStudentData();<\/p>\n<p>infile.read( (char*)&amp;sobj, sizeof(sobj));<\/p>\n<p>}<\/p>\n<p>infile.close();<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>int main()<\/p>\n<p>{<\/p>\n<p>writeStudents();<\/p>\n<p>&nbsp;<\/p>\n<p>readStudents();<\/p>\n<p>cout &lt;&lt;&#8220;Press any key &#8220;;<\/p>\n<p>cin.get(); cin.get();<\/p>\n<p>return 0;<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>Sample output of program is shown below.<\/p>\n<p>&nbsp;<\/p>\n<p>How many students to add? 2<\/p>\n<p>Enter student&#8217;s name: Tina<\/p>\n<p>Enter marks in 7 subjects:45 40 38 47 42 48 39<\/p>\n<p>Enter student&#8217;s name: Ali<\/p>\n<p>Enter marks in 7 subjects:48 43 40 37 36 47 45<\/p>\n<p>Name: Tina<\/p>\n<p>&nbsp;<\/p>\n<p>Marks: 45\u00a0 40\u00a0 38\u00a0 47\u00a0 42\u00a0 48\u00a0 39<\/p>\n<p>Name: Ali<\/p>\n<p>Marks: 48\u00a0 43\u00a0 40\u00a0 37\u00a0 36\u00a0 47\u00a0 45<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.6.1. <\/strong>Modify object stored in binary file<\/p>\n<p>&nbsp;<\/p>\n<p>Add function to modify marks of a specified student and write updated record back in binary file as shown here.<\/p>\n<p>&nbsp;<\/p>\n<p>void modifyMarks()<\/p>\n<p>{<\/p>\n<p>\/\/file for read\/write purpose, so use fstream class<\/p>\n<p>fstream file(&#8220;student.dat&#8221;, ios::in | ios::out | ios::binary);<\/p>\n<p>if (!file )<\/p>\n<p>{ cout &lt;&lt; &#8220;Error opening input file\u2026&#8221;, exit(3); }<\/p>\n<p>&nbsp;<\/p>\n<p>char name [40];<\/p>\n<p>&nbsp;<\/p>\n<p>cout &lt;&lt; &#8220;Enter name of student to modify marks: &#8220;; cin &gt;&gt; name;<\/p>\n<p>&nbsp;<\/p>\n<p>file.read( (char*)&amp;sobj, sizeof(sobj));<\/p>\n<p>while (!file.eof())<\/p>\n<p>{<\/p>\n<p>if (strcmp(name, sobj.getname())==0) \/\/ object found<\/p>\n<p>{<\/p>\n<p>sobj.getMarks();<\/p>\n<p>&nbsp;<\/p>\n<p>long pos = -1 * sizeof(sobj); \/\/for backward move file.seekp (pos, ios::cur); \/\/back from current file.write ((char*)&amp;sobj, sizeof(sobj));<\/p>\n<p>&nbsp;<\/p>\n<p>break;<\/p>\n<p>}<\/p>\n<p>file.read( (char*)&amp;sobj, sizeof(sobj)); \/\/read next<\/p>\n<p>&nbsp;<\/p>\n<p>}<\/p>\n<p>file.close();<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Calling modifyMarks() and readstudents() in main function will result in the following output:<\/p>\n<p>&nbsp;<\/p>\n<p>Enter name of student to modify marks: Tina<\/p>\n<p>Enter marks in 7 subjects:45 45 46 46 47 47 40<\/p>\n<p>&nbsp;<\/p>\n<p>after modification &#8230;<\/p>\n<p>Name: Tina<\/p>\n<p>Marks: 45\u00a0 45\u00a0 46\u00a0 46\u00a0 47\u00a0 47\u00a0 40<\/p>\n<p>Name: Ali<\/p>\n<p>Marks: 48\u00a0 43\u00a0 40\u00a0 37\u00a0 36\u00a0 47\u00a0 45<\/p>\n<p>&nbsp;<\/p>\n<p>Here, observe following points in the code:<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Use of fstream with input as well as output open mode<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>To modify marks of a specified student, it requires reading student, modifying marks if name is matching, and then writing student object back at the same position. Hence, one should use fstream class object for i\/o strem.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Positioning \u201cput\u201d pointer at the beginning of record before writing<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>After reading an object, file position is moved sizeof(sobj) bytes ahead. Before writing the updated object back, the position of \u201cput\u201d pointer should be moved sizeof(obj) bytes in backward direction.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.6.2.<\/strong>\u00a0\u00a0\u00a0 Delete an object from binary file<\/p>\n<p>&nbsp;<\/p>\n<p>Deletion of record from a file can be implemented using logical deletion or physical deletion.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">For logical deletion of an object, add one data member, say delFlag, in a class to mark the object as deleted. Now deletion is as good as modifying object by setting delFlag to true. A care should be taken while processing, like showing only non-deleted objects.<\/p>\n<p style=\"text-align: justify\">With physical deletion, an object record is to be removed from file. Due to sequential nature of streams, remaining records are to be shifted. It requires setting \u201cget\u201d and \u201cput\u201d pointer for all remaining records. The simple solution is to write remaining records in one temporary file and copying temporary file back to original file. This can be performed using following steps:<\/p>\n<p>&nbsp;<\/p>\n<p>(i) Create temporary file<\/p>\n<p>(ii) Read an object from data file<\/p>\n<p>(iii) If it matches with the specified object to be deleted, do not write in temporary file; otherwise write in temporary file<\/p>\n<p>(iv) Repeat steps (ii) and (iii) till end of data file<\/p>\n<p>(v) Close both files<\/p>\n<p>(vi) Delete original data file<\/p>\n<p>(vii) Rename temporary file as original data file<\/p>\n<p>(viii) rename(&#8220;temp.dat&#8221;, &#8220;marks.dat&#8221;);<\/p>\n<p>&nbsp;<\/p>\n<p>Refer following code using physical deletion of records from binary file.<\/p>\n<p>&nbsp;<\/p>\n<p>void deleteStudent()<\/p>\n<p>{<\/p>\n<p>&nbsp;<\/p>\n<p>ifstream infile(&#8220;student.dat&#8221;, ios::in | ios::binary); if (!infile )<\/p>\n<p>{ cout &lt;&lt; &#8220;Error opening input file\u2026&#8221;, exit(2); }<\/p>\n<p>&nbsp;<\/p>\n<p>ofstream tmpfile;<\/p>\n<p>&nbsp;<\/p>\n<p>tmpfile.open(&#8220;temp.dat&#8221;, ios::out | ios::binary); \/\/ copy objects in temp file if (!tmpfile.is_open())<\/p>\n<p>&nbsp;<\/p>\n<p>{ cout &lt;&lt; &#8220;Error opening input file\u2026&#8221;, exit(4); }<\/p>\n<p>&nbsp;<\/p>\n<p>char name [40];<\/p>\n<p>&nbsp;<\/p>\n<p>cout &lt;&lt; &#8220;Enter name of student to be deleted: &#8220;; cin &gt;&gt; name;<\/p>\n<p>&nbsp;<\/p>\n<p>infile.read( (char*)&amp;sobj, sizeof(sobj));<\/p>\n<p>while (!infile.eof())<\/p>\n<p>{<\/p>\n<p>if (strcmp(name, sobj.getname())!=0) \/\/ object not to be deleted<\/p>\n<p>{<\/p>\n<p>tmpfile.write ((char*)&amp;sobj, sizeof(sobj));<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>infile.read( (char*)&amp;sobj, sizeof(sobj)); \/\/read next<\/p>\n<p>}<\/p>\n<p>infile.close(); tmpfile.close();<\/p>\n<p>remove(&#8220;student.dat&#8221;); \/\/ remove old student.date file<\/p>\n<p>&nbsp;<\/p>\n<p>rename(&#8220;temp.dat&#8221;, &#8220;student.dat&#8221;); \/\/ rename temp.dat to student.dat<\/p>\n<p>}<\/p>\n<p>Write following lines in main() and execute program.<\/p>\n<p>&nbsp;<\/p>\n<p>deleteStudent();<\/p>\n<p>cout &lt;&lt; &#8220;\\nafter deletion &#8230; \\n&#8221;;<\/p>\n<p>&nbsp;<\/p>\n<p>readStudents();<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Observe the ouput:<\/p>\n<p>&nbsp;<\/p>\n<p>Enter name of student to be deleted: Tina<\/p>\n<p>&nbsp;<\/p>\n<p>after deletion &#8230;<\/p>\n<p>Name: Ali<\/p>\n<p>Marks: 48\u00a0 43\u00a0 40\u00a0 37\u00a0 36\u00a0 47\u00a0 45<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.6.3. Random access: Reading nth object from binary file<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>To access nth object from file without reading previous records, simply position \u201cget\u201d file pointer at (n-1)*sizeof(obj) bytes from beginning of file and read the record as follows.<\/p>\n<p>&nbsp;<\/p>\n<p>ifstream file;<\/p>\n<p>file.open(&#8220;student.dat&#8221;, ios::in | ios::binary);<\/p>\n<p>\/\/input n<\/p>\n<p>long pos = (n-1) * sizeof(sobj); \/\/for moving pos bytes ahead from beginning<\/p>\n<p>file.seekg (pos);\u00a0 \/\/ from beginning<\/p>\n<p>file.read ((char*)&amp;sobj, sizeof(sobj));<\/p>\n<p>sobj.ShowStudentData();<\/p>\n<p>file.close();<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Summary<\/strong><\/p>\n<ul>\n<li>Binary files are used for persistent storage of data in raw format o No type conversion or formatting takes place<\/li>\n<\/ul>\n<p>o\u00a0 Data stored in the format as it is stored in main memory<\/p>\n<ul>\n<li>Advantages of binary files over text files\n<ul>\n<li>o Faster input\/output operations<\/li>\n<li>o Storage apace efficient<\/li>\n<li>o Not editable using text editors<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li>While opening, requires ios::binary open mode to be specified alongwith other modes<\/li>\n<li>Input\/output operations can be performed using\n<ul>\n<li>o Methods read() and write() for any type of data; may be numeric, character,<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>string, struct, object etc.<\/p>\n<ul>\n<li>o Additionally, methods get() and put() can be used to read and write character data<\/li>\n<li>Random access and file error handling is same as with text files<\/li>\n<\/ul>\n<p><strong>References<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>1) Stanley Lippmann, \u201cC++ Primer\u201d, Pearson Education.<\/p>\n<p>2) Bjarne Stroustrup, \u201cThe C++ Programming Language\u201d, Pearson Education.<\/p>\n<p>3) Scott Mayer, \u201cEffective C++\u201d, Addison Wesley.<\/p>\n<p>4) Bhushan Trivedi , Programming with ANSI C++, 2\/e , Oxford University Press.<\/p>\n<p>5) Yashavant P. Kanetkar \u201cLet Us C++\u201d , Bpb Publications.<\/p>\n<p>6) Abhiram G. Ranade, \u201cAn Introduction to Programming through C++\u201d , McGraw Hill<\/p>\n<p>7) Ellis and B. Stroustrup \u201cAnnotated C++ Reference Manual\u201d, http:\/\/www.stroustrup.com\/arm.html<\/p>\n<p>8) Herbert Schildt, \u201cComplete Reference C++\u201d, McGraw Hill Publications.<\/p>\n<p>9) Ashok Kamthane, \u201cObject Oriented Programming with ANSI and Turbo C++\u201d, Pearson Education<\/p>\n<p>10) E Balaguruswami, \u201cObject Oriented Programming With C++\u201d, Tata McGraw Hill<\/p>\n<p>11) \u201cC++ FAQs\u201d, Pearson Education.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"author":4,"menu_order":29,"template":"","meta":{"_acf_changed":false,"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":["dr-jyotika-doshi"],"pb_section_license":""},"chapter-type":[],"contributor":[60],"license":[],"class_list":["post-213","chapter","type-chapter","status-publish","hentry","contributor-dr-jyotika-doshi"],"part":3,"_links":{"self":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/pressbooks\/v2\/chapters\/213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/wp\/v2\/users\/4"}],"version-history":[{"count":3,"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/pressbooks\/v2\/chapters\/213\/revisions"}],"predecessor-version":[{"id":294,"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/pressbooks\/v2\/chapters\/213\/revisions\/294"}],"part":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/pressbooks\/v2\/parts\/3"}],"metadata":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/pressbooks\/v2\/chapters\/213\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/wp\/v2\/media?parent=213"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/pressbooks\/v2\/chapter-type?post=213"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/wp\/v2\/contributor?post=213"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/itp1\/wp-json\/wp\/v2\/license?post=213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}