Fread/fwrite, and freadfwrite

Source: Internet
Author: User

Fread/fwrite, and freadfwrite

Today, I continue to look at what cool people have done. This small program is not large. With a lot of comments, there are only over 5000 lines. This small program is implemented in linux. I have been using vi For more detailed comments, but the efficiency is too low. So transfer it to windows and decide to transform it to VS2012 for running.

This is a pure C Code. The new project is C ++, and the forced type conversion is used in the code to convert one struct type to another struct type. Therefore, an error cannot be returned during compilation. Finally, I created a new empty project and imported it as an existing file to solve this problem. After some problems are modified, no error is reported and you can run the task. But the really sad thing started to happen.

First, an error is reported after running. After the file read/write error is identified, an exception is added to the place where the file is opened in the original code. But it is still wrong. Single-step discovery

while(fread(&record,sizeof(RECORD_TYPE),1,fp_data)==1)

The returned value of fread is always 0. Because the value of sizeof (RECORD_TYPE) is 128, the above Code is changed

while(fread(&record,1,128,fp_data)==128)

Let's take a look at it one by one. It's strange that the value returned this time is 33. Think twice about it. Then I took out the code and did not place it in the while LOOP, as shown below:

Fseek (fp_data, 0L, SEEK_END); // offset all files tail pos = ftell (fp_data); // read the position fseek (fp_data, 0L, SEEK_SET ); // offset to the file header err = fread (& recode, 1,128, fp_data); // read a record pos = ftell (fp_data); // read location

After debugging, we found that the value of the previous ftell was 81792, and the value of the other ftell was 4096. It is even more confusing. The file does not reach the end of the file. The file is large enough to read 4096/81792. However, it is clear that only 128 bytes are read, and 128*8 should be 1024 bytes, why does 2nd ftell return 4096? In this case, I am a little flustered. Although it is worth noting that fread is put back on MSDN, it has not been put into practice. Finally, du Niang told me this Website: http://www.360doc.com/content/11/0128/16/2150417_89591799.shtml.

/* Read binary data in text mode. a certain segment of data may be considered as EOF at the end of the file before the end of the file, so the reading ends (for example, for example, if 0x00 0x00 0xff 0xff is encountered, the file stream in text mode is considered to be at the end of the file and cannot be read )*/

I instantly understood the cause of the error. Modify the previous Code and try again:

Fseek (fp_data, 0L, SEEK_END); // offset all files tail pos = ftell (fp_data); // read the position fseek (fp_data, 0L, SEEK_SET ); // offset to the file header err = fread (& recode, 1,128, fp_data); // read a record pos = ftell (fp_data ); // read location err = feof (fp_data); // whether the object has reached the end of the file. If the value is not 0, it indicates that the object has ended and the value 0 indicates no. For the specific usage of feof, see msdn

The feof return value is 16, not 0, and the expression is at the end of the file. Therefore, it is determined that fread encountered an EOF flag when reading data. The correction method is to change the mode parameter in fopen to 'rb', that is, to read data from text to binary streams. As follows:

// If (err = (fopen_s (& fp_data, "data", "r "))! = 0) // printf ("open file data failed \ n"); // open the data file if (err = (fopen_s (& fp_data, "data ", "rb "))! = 0) printf ("open file data failed \ n"); // open the data file

This problem is finally solved. I thought this solved the problem. But it is in a more troublesome situation.

Click "run" again. It is also a running error. I followed in and found that the pointer to a tree is null, but the value is assigned. Now, I have called this node to apply for a space! Is it malloc failure? Immediately add a judgment to the location of malloc. Unfortunately, there is still no progress at all. Let's look at the author's idea of writing code. Before applying for space for this node, first judge whether the value of a is equal to B. If not equal, print a message to create a tree node and fail, but do not terminate the program, and certainly do not apply for space. Oh, well, let's see when this will happen. Find the above Code section of the Code, one piece of the code, and several if-else write 100 or 200 lines. But you can still understand it.

The author's code is roughly as follows:

If (a <B) {//... a large code segment, dozens of lines} else {if (! = B) {print (""); return FALSE;} // request a space for the node //... a large code segment}

So I am very happy to think that even the cool man like the author will be confused, and I think it should be a here! Change = B to a> = B. Whether it can be changed or not, change it first. But after the change, run it and report an error this time. However, this is not the case. For single-step debugging, it's strange how the value of a is too big. First look at the Code:

// Here, a, B, c, and d are not in the original state of the program, but are simplified for illustration. found = FALSE; if (a <B) {I = 0; while (! Found & I <a) {if (c> = d [I]) {// Where B is the size of array d I ++ ;} else {found = TRUE; }}// other code}

The value of B is 29, but the value of a is 5029. It's strange not to cross-border. This explains why only a <B and a are judged in the previous code! = B, but not a> B, because once a> B, an error occurs.

How can this happen?

Where is the error ???

I thought of it, will it still be an error when reading the file? Is it because binary files are read as text files, which affects the value of? Locate all the places where fopen is used and add the mode parameter to 'B '.

Click "run" again. The problem is solved.

Summary

Such a farce can finally be ended, because the fread function is a disaster.

/* The text cannot be completely read, but the reason for the binary mode is that the file is read in the text mode. The most important use is to read the entire sentence at a time (with the line break '\ n ', that is, the line feed sign "\ r \ n" of binary is ended. It is used for ReadString, fscanf (..., "% s ",...) and so on, the length of each Read content is not fixed; while the binary Read mode Read, fread, etc., are Read fixed length, so the text Read Method to Determine the EOF, is the end of a file mark, if it is a text file, the end of the file will certainly not appear in the file content (because it is an end sign consisting of non-printable characters, a readable text file will not include it ), in this way, the end mark is the end of the file. The binary file content can be any byte. If you read it as a text file, it ends with the end of the file, of course, the file content may be determined as the end of the file. The binary reading method only needs to use the total file length (this value is a value managed by the System) because the fixed bytes are read each time, calculated) minus the length of each read (or the length is calculated based on the location of the Seek), you can know whether it is at the end of the file without defining the end mark; therefore, it is reasonable to open any file in binary mode */

At this point, I also understood that the author ended the loop by reading whether the data volume is equal to the data volume required by the count parameter in fread, rather than determining through feof.

Finally, you must understand that when using fread/fwrite, tens of millions of records are read in binary format.

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.