In those years, the fread/fwrite of the pit of his own death.

Source: Internet
Author: User
Tags recode

Today we continue to see what the cattle have done, this small program is not very big, plus a considerable number of comment lines, only more than 5,000 lines. This small program is implemented under Linux, and has been used to look at the VI and more detailed comments, but the efficiency is too low. Then transfer it to Windows and decide to retrofit to VS2012 under run.

This is a pure C code, the new project is C + +, and the code uses a forced type conversion to convert a struct type to another struct body. So when compiling the error can not pass. Finally, I created an empty project and imported it in the form of an existing file to solve this problem. After modifying some problems, finally no error, can run. But the real tragedy began to happen.

First, after running the error, determined that the file read and write errors, the original code to open the file in the place to add exception handling. But it's still a mistake. Stepping in to find out

 while (Fread (&record,sizeof(record_type),1, fp_data) = =1)

There is no way to enter the loop, and the return value of Fread is always 0. Because sizeof (RECORD_TYPE) has a value of 128, the above code is changed to

 while (Fread (&record,1,fp_data) = =)

One more step at a time, it's strange that the return value has changed to 33. The solution is not to be baffled. I then take this code out, not in the while loop, as follows:

Fseek (Fp_data,0L, seek_end); // offset all file tail Pos=ftell (fp_data); // read the tail position fseek (fp_data,0L, Seek_set); // offset to file head err = fread (&recode,1,fp_data); // read a record pos = Ftell (Fp_data); // Read Location

After debugging, we find that the value of the previous ftell is 81792, and the return value of the last Ftell is 4096. It's more puzzling than that. The file does not reach the end of the file, the file is large enough to read 4096/81792, but, obviously only read 128 bytes, 128*8 should be 1024, how the 2nd Ftell returned 4096? In this case, a bit of a panic. Although it is worth noting that the Fread on MSDN has been put back, it has not been practiced. Finally Niang told me this URL http://www.360doc.com/content/11/0128/16/2150347_89591799.shtml.

/**/

Instantly understood the cause of the mistake. Modify the previous section of the Code and try again:

Fseek (Fp_data,0L, seek_end); // offset all file tail Pos=ftell (fp_data); // read the tail position fseek (fp_data,0L, Seek_set); // offset to file head err = fread (&recode,1,fp_data); // read a record pos = Ftell (Fp_data); // Read position err = feof (fp_data); // whether to reach the end of the file, not 0 is after the end of the file, 0 is no; feof specific usage See MSDN

Get the feof return value 16, not 0, the expression passed through the end of the file. Thus, it is concluded that fread read the data when encountering the wrong EOF flag. The Fix method is to change the mode parameter in fopen to ' RB ', which is read by the text mode read to the binary stream. As follows:

 // if (Err= (fopen_s (&fp_data, "data", "R")) = 0)  //  printf ("Open File data Failed\n ");  //  Open Data file   (err= (fopen_s (&fp_data,"  data  , "   RB  ))! = 0  ) printf (    "); //  

The problem has finally been solved. The problem was resolved by a full thought. Is in a more troubling situation.

Click Run again, and it is a run-time error. Follow up to find out that the pointer to a tree appears empty, but it is assigned. Again see clearly called to this node to apply for space Ah! is malloc a failure? Immediately add judgment to malloc's place. Unfortunately, there is still little progress. Then look at the author's idea of writing code, to the node before the application of space, the first to determine whether a value is equal to B, if not equal, then print a message new tree node failed, but do not terminate the program, of course, do not apply for space. Oh, that's it, so look at when this happens. Find this code in the above section of code, a dense piece, a few if-else wrote one hundred or two hundred lines. But I can still get a general idea.

The mind startled, found the problem, the author code is roughly as follows:

if (A < b) {    //..... A large piece of code, good dozens of rows }else{    if (A! = b)    {        print ("" );         return FALSE;    }     // Apply space    to a node // ...... A large piece of code }

So I am happy to think that even the author of such a cow will be confused, think it is supposed to be here, a! = B to a >= B. No matter it can not change, first change to say. But after the change, run, this time or error, but it is not this place. Single-step debugging, the value of this a is too big to play too strange. Look at the code first:

 //  here a,b,c,d, etc. are not the same in the program, but simplified for illustration purposes     found=false;  if  (a < b) {i  = 0  ;  while  (!found && i<a) {if  (c >=d[i]) {//  b is the size of the array d  i++ else   {found  = TRUE; }}  //  other code } 

Another look at the value of B is 29, but the value of a is 5029. It's strange not to cross the border. It is also clear from here why the previous code only judges a < b and a! = B and does not process a > B, because once a > b is wrong.

How did this happen when I looked back?

What the hell is wrong???

Think of a bit, will still be reading the file when the error? Is it possible to read a binary file as a text file stream, affecting the value of a? Decisively find all the places that use fopen, add a ' B ' to the mode parameter.

Click to run again, sure enough, the problem is solved.

Summarize

Such a farce can finally end, all because fread this function to curse.

/* text mode cannot be fully read, and binary mode can be the reason-the text way to read the file, the most important use is to read an entire sentence at a time (with the newline character ' \ n ', that is, the binary line-break flag "\ r \ n" end), convenient for special use ReadString, fscanf (..., "% S ",...) The content length of each read is variable; While the binary reading mode read, Fread, and so on, are read fixed length, so the text way to read the decision of EOF, is a file tail end flag, if it is a text file, then the end of this file will not appear in the file content (because it is a non-printable character of the end of the flag, A human-readable text file does not include it), so it is possible to end the file with the ending mark; Binary file content can be any byte, if it is used as a text file to read, the end of the file, of course, may appear to determine the contents of the file to the end of the case; Binary read mode because each read fixed byte, so only need to use the total file length (this value is a system management value, not calculated) minus the length of each read (or calculate the length according to the location of seek), you can know whether to the end of the file, do not need to define the end flag; So it is reasonable to open any file in binary mode * /

It is also understood that the author ends the loop by reading whether the amount of data is equal to the amount of data required by the count parameter in Fread, rather than by feof.

Finally, it is important to understand that when using Fread/fwrite, you must remember to read in binary form .

In those years, the fread/fwrite of the pit of his own death.

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.