fread/fwrite issues

This is a discussion on fread/fwrite issues within the C Programming forums, part of the General Programming Boards category; Well, this is kind of a mountain of a question/bug. I'm using ftell() to ascertain the size of the file ...

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    4

    Question fread/fwrite issues

    Well, this is kind of a mountain of a question/bug. I'm using ftell() to ascertain the size of the file after a certain point, malloc() a buffer that size, use fread() to get the information, write my information in, write the information read earlier back in with fwrite()...and it seems like it works, but I get a massive white space overflow at the end of the file. For the complete code, copy this link into your browser: http://wryle.tripod.com/xml/news.zip. The following is the code in question, followed by the file I'm reading/writing from/to:

    Code:
    char *buf;
    ...
    //inside a switch case
    fp = fopen( MIni.GetCurrentData(), "r+" );
    if (fp)
    {
    //set position to right after <entries>    
    //get size of file
    fseek(fp, 0, SEEK_END);
    flen = ftell(fp);
    cout << "Whole file: " << flen << endl;
    fseek(fp, 35L, SEEK_SET);
    flen_2 = ftell(fp);
    cout << "Header: " << flen_2 << endl;
    flen = flen-flen_2;
    cout << "Whole file - Header: " << flen << endl;
         				  
    fseek(fp, 35L, SEEK_SET);
    		  
    buf=(char *)malloc(flen);
    //fill the buffer in
    fread(buf, flen, 1, fp);
    	  			  
    fp = fopen( MIni.GetCurrentData(), "w+" );
    if (fp)
    {
      rewind(fp);
    			  
      cout << "File \""<<MIni.GetCurrentData()<<"\" already exists.\nPosting...\n";
    		
      cout << "Message Title: ";
      cin.getline(msg.title,256);				
      cout << "Message Body: ";
      cin.getline(msg.message,4096);
      cout << "E-Mail Address: ";
      cin.getline(msg.email,256);
      cout << "Username: ";
      cin.getline(msg.user,256);
      cout << "Date to be posted: ";
      cin.getline(msg.date,256);
      fprintf( fp, "<?xml version=\"1.0\"?>\n\n");
      fprintf( fp, "<entries>\n");
      fprintf( fp, "\t<entry>\n");
      fprintf( fp, "\t\t<title>%s</title>\n", msg.title);
      fprintf( fp, "\t\t<message>%s</message>\n", msg.message);
      fprintf( fp, "\t\t<email>%s</email>\n", msg.email);
      fprintf( fp, "\t\t<user>%s</user>\n", msg.user);
      fprintf( fp, "\t\t<date>%s</date>\n", msg.date);
      fprintf( fp, "\t</entry>");
      fwrite(buf, flen, 1, fp);
      fclose( fp );
      cout << "Successfully added.\n";
    		  
    }
    ...
    The file:
    Code:
    <?xml version="1.0"?>
    
    <entries>
    	<entry>
    		<title>Test entry</title>
    		<message>Test entry message</message>
    		<email>cbrhtrash@netscape.net</email>
    		<user>elios</user>
    		<date>08.09.2003</date>
    	</entry>
    </entries>
    Thanks in advance,
    --elios

  2. #2
    Registered User
    Join Date
    Aug 2003
    Posts
    4

    Response

    > Tried to download your code and got this...

    Right-click the link and "Save Target As...".

    >Also, what's with the mis-mash of C and C++ features?

    Quite frankly, because I can. I learned C first and used it for 4 years, and then I learned C++. So all of my programs do something like that. In this case, it is to get a filename from a file called "settings.ini" (using some else's library, of course).

    >fseeking like this into the middle of a text file is not a good idea.
    >In text mode, the file may be subject to character translations
    >(like \r\n pairs becoming \n) which will throw off fseek().
    >Ideally, you should only call fseek() to the interior of a text file
    >using the result of a previous ftell() call.

    I wasn't aware of that. Is there any way around that?

    Thanks again,
    --elios

  3. #3
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >> I wasn't aware of that. Is there any way around that?
    Depends on what you want. You can start at the beginning of the file, and read your way into it; fseek() to an undefined location and try to correct the positioning yourself (not recommended); use binary IO; and probably a few more options.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  4. #4
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    do you know exactly what you're looking for in your fseek() call? If you do you can fgetc()(slow) or fgets() and compare it to whatever you're looking for.

  5. #5
    Registered User
    Join Date
    Aug 2003
    Posts
    4

    Unhappy Better Explanation

    Sorry for the incredible delay in posting, but...First, let me give a better explanation of what I'm trying to do, just so that everything is clarified.

    First off, this program's goal is to post an entry into a an XML file that will be read by a PHP file and interpreted into a formatted entry. The PHP script will give an error if the XML is screwy (which is why I posted). Second, this file will not be edited by a user externally (provided I get the bug fixed ). Third, there are preset things, like the header is 35 characters long (with escape chars included) and the footer is 7 characters long. Fourth, I can append an entry by using fseek to go back 7 characters and then inserting the entry with fprintf over it. Fifth, the entries aren't a set length (the message can be huge and on multiple lines). Last, the problem, I can't seem to get the right amount of memory allocated for a buffer to hold the remainder of the file (i.e. file with the header removed); there always seems to be extra character data (which, I assume, is what didn't get filled in, but was allocated).

    Okay. Now, let me explain how the entry is inputed into the file. The user opens the program and is allowed to change certain things (like settings in the ini file), but they can also post an entry, which has to be put at the top of the file (i.e. right after the header) so that it gets read in as the first entry by the PHP file. Alright, the way I logically thought I could do this is as follows: fseek to the end of the header, copy the rest of the file to a buffer with allocated memory based on the size of the file, post the entry submitted by the user into the file, and post the buffer back into the file after it. Hmm, I guess I was wrong...

    do you know exactly what you're looking for in your fseek() call? If you do you can fgetc()(slow) or fgets() and compare it to whatever you're looking for.
    Yes, I do know what I'm looking for, but let me make sure I understand what you're suggesting. Are you suggesting I just read everything into a buffer that way (like with a while loop waiting for EOF)?

    Thanks again for the suggestions,
    --elios

    P.S. zip file is too big (well, the current one atleast)
    Last edited by elios; 08-16-2003 at 08:41 PM.

  6. #6
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    This example will let you append the file, then it writes your footer back in, without having to mess with the rest of the file. Be Careful: This example directly manipulates the file, without copying it or having the ability to save it somewhere else. I haven't done much work with files before, so it wouldn't hurt for someone else on the board to double check my work
    Code:
    #include<stdio.h>
    #include<errno.h>
    
    char buf, footer[8];
    FILE *fpin;
    
    fseek(fpin,-16L,SEEK_END); /*seeks 8 chars before end of file*/
    
    fgets(footer,sizeof(footer),fpin) /*reads footer into its own array*/
    
    /*clears fpin of EOF reading*/
    clearerror(fpin);
    /*puts file cursor right before the 7 char footer*/
    fseek(fpin,-14L,SEEK_END); 
    
    /*writes append info to file one character at a time until enter is pressed*/
    for( ; buf!='/r' ; fwrite(*buf,sizeof(buf),1,fpin) ) 
    
    fwrite(footer,sizeof(footer),1,fpin); /*writes footer back into file*/
    Last edited by Draco; 08-17-2003 at 12:11 PM.

  7. #7
    Registered User
    Join Date
    Jul 2003
    Posts
    61
    elios: you have a '.' (dot) at the end of your original link, what's why people are getting 404 errors.
    $ENV: FreeBSD, gcc, emacs

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    4

    whoops


Popular pages Recent additions subscribe to a feed

Similar Threads

  1. array issues
    By Rob123 in forum C Programming
    Replies: 9
    Last Post: 04-26-2009, 10:35 AM
  2. Speed issues
    By Govtcheez in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 04-22-2005, 04:06 AM
  3. SQL Connection issues
    By jverkoey in forum Tech Board
    Replies: 4
    Last Post: 02-17-2005, 07:52 AM
  4. Memmory Issues and Threads
    By ddod in forum Windows Programming
    Replies: 2
    Last Post: 08-13-2004, 11:30 AM
  5. hexdump issues
    By daluu in forum C Programming
    Replies: 2
    Last Post: 03-04-2003, 09:01 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21