Detailed reading and writing of binary files in C + + programming _c language

Source: Internet
Author: User

Binary files do not hold data in ASCII code, which transmits the form of data stored in memory to disk files without conversion, so it is also known as an image file of memory data. Because the information in the file is not a character data, but a binary form of information in the byte, it is also called a byte file.

For binary files, you need to open the file first, and then close the file when you are finished. When opened, it is specified with ios::binary to be transferred and stored in binary form. In addition to being an input file or output file, binary files can be both input and output files. This is a different place from the ASCII file.
Reading and writing binary files with member functions read and write

The reading and writing of binary files are mainly implemented by the member functions of the IStream class, read and write. The prototypes for these two member functions are

  istream& Read (char *buffer,int len);
  ostream& Write (const char * buffer,int len);


The character pointer buffer points to a storage space in memory. Len is the number of bytes read and write. The method is called:

  A. Write (p1,50);
  B. Read (p2,30);


A is the output file stream object in the first line above, and the write function writes the 50-byte contents of the P1 of the character pointer to the disk file without converting it. In the second row, B is the input file stream object, and the Read function reads 30 bytes (or at the end of EOF) from the disk file associated with B, and is stored in a space within the meaning of the character pointer P2.

[Example] A batch of data is stored in binary form in a disk file.

#include <fstream>
using namespace std;
struct student
{
  char name[20];
  int num;
  int age;
  char sex;
};
int main ()
{
  student stud[3]={"Li", 1001,18, ' f ', "Fun", 1002,19, ' m ', "Wang", 1004,17, ' f '};
  Ofstream outfile ("Stud.dat", ios::binary);
  if (!outfile)
  {
   cerr<< "open error!" <<endl;
   Abort ()//Exit program
  } for
  (int i=0;i<3;i++)
   outfile.write ((char*) &stud[i],sizeof (stud[i
   )); Outfile.close ();
  return 0;
}

With the member function write to Stud.dat output data, from the previous write function of the prototype can be seen: the 1th parameter is to point to the char type constant variable of the pointer variable buffer, because the const declaration is because the pointer is not allowed to change its value to the data. The parameter requires the corresponding argument to be the first address of the character pointer or string. Now you want to output one element of the structure array (including 4 members) to the disk file Stud.dat. &tud[i] is the first address of the element in the structure body array, but this is a pointer to the struct body and does not match the formal parameter type. Therefore, use (char *) to cast it to a character pointer. The 2nd parameter specifies the number of bytes to output at a time. The value of sizeof (Stud[i]) is the number of bytes of an element in the structure array. Calls the Write function, outputting an element of the structure array starting from &tud[i to the disk file, and executes the 3 elements of the 3-time circular output structure array.

In fact, you can output the elements of a struct array at once, changing the two lines of the For loop to the following line:

  Outfile.write ((char*) &stud[0],sizeof (stud));


Performing a write function outputs all the data for the structure array.

The role of the Abort function is to exit the program, with the same effect as exit.

It can be seen that this method can output a batch of data at a time, the efficiency is high. You do not have to add a space between the output data, and you do not have to add a carriage return line break after one output. When you later read data from the file, you do not use the space as the interval for the data, but you control the number of bytes.

[Example] reads the data that was just in binary form in the disk file into memory and displays it on the monitor.

#include <fstream>
using namespace std;
struct student
{
  string name;
  int num;
  int age;
  char sex;
};
int main ()
{
  student stud[3];
  int i;
  Ifstream infile ("Stud.dat", ios::binary);
  if (!infile)
  {
   cerr<< "open error!" <<endl;
   Abort ();
  }
  for (i=0;i<3;i++)
  Infile.read ((char*) &stud[i],sizeof (stud[i));
  Infile.close ();
  for (i=0;i<3;i++)
  {
   cout<< "NO." <<i+1<<endl;
   cout<< "Name:" <<stud[i].name<<endl;
   cout<< "num:" <<stud[i].num<<endl;;
   cout<< "Age:" <<stud[i].age<<endl;
   cout<< "Sex:" <<stud[i].sex<<endl<<endl;
  }
  return 0;
}

Display on the monitor at run time:

No.1
Name:li
num:1001
age:18
sex:f
No.2 name:fun num:1001 age:19 Sex:m

No.3
name:wang
num:1004
age:17
sex:f

Consider whether you can read all the data in the file at once, such as:

  Infile.read ((char*) &stud[0],sizeof (stud));

The answer is yes, the specified number of bytes is read into memory, and then stored in the storage space starting with address &tud[0. Be aware that the data you read is formatted to match the format of the space in which it is stored. Because the data in the disk file is derived from an array element in an in-memory structure, it retains the data format of the structure element. Now read into the memory, stored in the same structure of the array, which must be matched. If you put it in an integer array, it does not match and there is an error.
Flow member functions related to file pointers

There is a file pointer in the disk file that indicates where the current should be read and write. Each time you read a Yu section at input, the pointer moves one byte backwards. Each byte of output to the file is exported, and the pointer moves back one byte, and the pointer is moved back and forth as the bytes in the output file increase. For binary files, the pointer is allowed to be controlled so that it is moved to the desired location in order for the user to read and write at that location. The file stream provides some member functions about the file pointer. For ease of reference, they are summarized in the following table:

A few notes:
1 The first letter or the last letter of the function name is either G or P. The G is for the input function (g is the first letter of Get, with G as the input of the identification, easy to understand and memory), with P is the function for the output (P is put the first letter, with p as the output of the identification). For example, there are two tell functions, tellg for input files, and TELLP for output files. Similarly, SEEKG is used for input files, SEEKP for output files. The above function sees the name to know the meaning, at a glance understands, does not need to rote.

If it is a file that can be both entered and output, use either SEEKG or SEEKP.

2 the "position in file" and "offset" in the function argument are specified as long integers in bytes. The reference location can be one of the following:
The Ios::beg file begins (Beg is the abbreviation for begin), which is the default value.
The current position of the ios::cur pointer (cur is the abbreviation for present).
Ios::end the end of the file.
They are enumerated constants defined in the iOS class. Examples are as follows:
INFILE.SEEKG (100); The pointer in the input file moves forward to the byte position
INFILE.SEEKG ( -50,ios::cur); The pointer in the input file moves bytes from the current position
OUTFILE.SEEKP ( -75,ios::end); The pointer in the output file moves bytes from the end of the file
Random access to binary data files

In general, read and write is in order, that is, read-write bytes by byte. But for binary data files, you can use the member function above to move the pointer, randomly access the data in any location in the file, and modify the contents of the file.

[Example] There is a student's data that asks:
Save them in a disk file;
Read the first, 3, 5 student data in the disk file into the program and display it;
Change the data of the first student back to the original location in the disk file.
Read the revised student's data from the disk file and display it.

To achieve these requirements, you need to address a problem:
Because the same disk file requires frequent input and output in your program, you can specify how the file works as an input/output file, that is, ios::in|ios::out|ios::binary.
Correctly compute the position of the pointer on each access, that is, use the SEEKG or SEEKP function correctly.
Rewrite (update) the data in the file correctly.

The following procedures can be written:

#include <fstream> using namespace std;
  struct student {int num;
  Char name[20];
Float score;
};
  int main () {student stud[5]={1001, "Li", 85,1002, "Fun", 97.5,1004, "Wang", 54,1006, "Tan", 76.5,1010, "Ling", 96};
  FStream iofile ("Stud.dat", ios::in|ios::out|ios::binary); Define the input output binary file stream object Iofile if (!iofile) {cerr<< "open error!" with the FStream class
   <<endl;
  Abort ();
  for (int i=0;i<5;i++)//output a student's data to a disk file Iofile.write ((char *) &stud[i],sizeof (stud[i)); Student Stud1[5]; Used to hold the data read from the disk file for (int i=0;i<5;i=i+2) {iofile.seekg (i*sizeof (stud[i)), Ios::beg);//positioning at 2, 4 student data start//Read a study
   Raw data, stored in stud1[0],stud[1] and stud[2] in Iofile.read ((char *) &stud1[i/2],sizeof (stud1[0)); Outputs stud1[0],stud[1] and stud[2] the values of each member cout<<stud1[i/2].num<< "" <<stud1[i/2].name<< "<<
  stud1[i/2].score<<endl;
  } cout<<endl; stud[2].num=1012;
  Modify the data strcpy (Stud[2].name, "Wu") of the first student (serial number);
  stud[2].score=60; IOFILE.SEEKP (2*sizEOF (Stud[0]), Ios::beg); Positioned at the beginning of the first Student data iofile.write ((char *) &stud[2],sizeof (stud[2)); Update the first Student data iofile.seekg (0,ios::beg); Relocate to the beginning of the file for (int i=0;i<5;i++) {iofile.read ((char *) &stud[i],sizeof (stud[i)); Read a student's data cout<<
  stud[i].num<< "" <<stud[i].name<< "" <<stud[i].score<<endl;
  } iofile.close ();
return 0;
 }

The operating conditions are as follows:

1001 Li 85 (First student data) 1004 Wang (First student    data)
1010 Ling    (First student data)

1001 Li     (output modified student data)
1002 Fun 97.5
1012 Wu     (revised first student data)
1006 Tan 76.5 1010 Ling
96

This program can also be a disk file Stud.dat successively defined as output files and input files, close the file after the first output is finished, and then open it as input, and then close it as you enter it, then open it as output, then close it, and then turn it back on as input. Obviously this is very cumbersome and inconvenient. Specify it as the input-output binary file in the program. This allows you to add new data or read data to the file, as well as modify (update) the data. With these features, you can achieve more complex input and output tasks.

Note that you cannot use the Ifstream or Ofstream class to define binary file stream objects for input and output, but instead use the FStream class.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.