Solved

need help finding bug in buffer to file swap program

Posted on 2004-10-15
5
266 Views
Last Modified: 2010-04-01
I have a program that's supposed to read in half of a file to buffer then reads in the other half while replacing it with the reversed 1st half (byte by byte), and finally, goes back to beginning of file to write reversed 2nd half into the 1st half. But I get a bug, that sticks an extra character at the end of the file when running the program. I can't find it. Can you help me find this bug.

for an input file of 4 bytes with content: todo
running the program gives me : odoto
instead of giving me the desired odot

here's the code. I traced the problem to the swaphalves() function but can't spot the bug.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*fncs*/
long FileSize (FILE *stream);
void readfirst(char* buffer);
void writefirst(char* buffer);
void swaphalves(char* buffer);

//Declare global variables
//Global variables used to avoid passing variables into functions
FILE *dfile; //file handle for database file
long fsize; //var used to calculate filesize
long readto; //var used to read/write half of file

int main(int argc,char *argv[])
{      
      //1 - check input
      if (argc<2)
      {
            puts("No input file specified. Please type command again with filename.\n");
            return 0;//Self explanatory
      }
      
      //2 - Open input file
      dfile = fopen(argv[1], "rb+");
      //Abort program & display error if file open fails
      if(dfile==NULL)
      {
            printf("Bad filename or file does not exist.\n");
            return 1;
      }

      //3 - Get file size
      fsize = FileSize(dfile);
      readto = fsize/2;
      //not dealing with ODD file size cases at present
      
      char *buffer;
      buffer = (char*) malloc( sizeof(char)*readto );
      
      //4 - read in half of file contents
      readfirst(buffer);

      //5 - swap contents in buffer w/ content in 2nd half of file
      swaphalves(buffer);

      //6 - write back swapped half of file to 1st half of file
      writefirst(buffer);      

      //7 - Notify operation complete
      puts("Half file swap operation completed.\n");
      
      //8 - Exit program
      free(buffer);
      fclose(dfile);
      return 0;
}

long FileSize (FILE *stream)
{
      long length;//temp variable
      fseek (stream, 0L, SEEK_END);//seek to EOF
      length = ftell(stream);//store EOF byte position which is filesize
      //reset file for future reading by seeking to origin
      fseek (stream, 0L, SEEK_SET);
      return length;//return filesize
}

void swaphalves(char* buffer){

      int nread = (int) readto;  //counter to check EOF
      int fend = (int) fsize;         //indicates EOF
      int byte;               //tmp var to stor a byte
      long back = -1L;         //var for seeking back 1 byte
      int revpos = (int) readto; //counter for reversing buffer contents
      revpos--;               //workaround as ((int) readto) - 1 gave bad result
      
      while(((byte = fgetc(dfile)) != EOF) && (nread < fend)){
            
            //loop to swap a byte from current file pos with current buffer pos

            //put back last byte in buffer to file, seek back 1
            fseek(dfile,back,SEEK_CUR);
            fputc(buffer[revpos],dfile);
            //file ptr will auto mov to original pos after call to fputc
            
            //put latest byte read from file to end of buffer & decrement buffer position
            buffer[revpos--] = (char) byte;
            
            //get next byte in file in next while loop
            nread++; //increment # bytes read indicator
      }

      return;
}

void writefirst(char* buffer){
      fseek (dfile, 0L, SEEK_SET);
      //fwrite(buffer,sizeof(char),length,afile);
      fwrite(buffer,readto,1,dfile);
      return;
}

void readfirst(char* buffer){
      fread(buffer,readto,1,dfile);
      return;
}
0
Comment
Question by:daluu
  • 4
5 Comments
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12326553
Your prog works fine.

Check your input file not including any CR LF characters and try again.

Regards, Alex
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12326579
I tried your prog again - now using the file that was written the first time - and it failed. The problem is the filesize function that returns length 5  but 4 when reading the newlyy written file. After that variable readto is 2 - that's a bug of your prog that cannot handle odd lengths - and all failed after that.

I'll try to find out where you put the extar character non visible to the file.

Regards, Alex
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 250 total points
ID: 12326660
Ok, i think i found it. It's the while loop in swaphalves where you are reading (fgetc) and putting (fputc) the same time. The problem is that one of the putc works as 'insert' rather than an overwrite as you do a repositioning while reading the file. Your comment "" is wrong as fileposition has to be moved to the position after last fgetc.
void swaphalves(char* buffer){

     int nread = (int) readto;  //counter to check EOF
     int fend = (int) fsize;        //indicates EOF
     int byte;             //tmp var to stor a byte
     long back = -1L;        //var for seeking back 1 byte
     long curr;
     int revpos = (int) readto; //counter for reversing buffer contents
     revpos--;             //workaround as ((int) readto) - 1 gave bad result
     
     while(nread > 0){
         
          //loop to swap a byte from current file pos with current buffer pos
          byte = fgetc(dfile);
          curr = ftell(dfile);
          //put back last byte in buffer to file, seek back 1
          fseek(dfile,back,SEEK_CUR);
          fputc(buffer[revpos],dfile);
          //file ptr will auto mov to original pos after call to fputc // NO, IT DOESN'T
          fseek(dfile, curr, SEEK_SET);

          //put latest byte read from file to end of buffer & decrement buffer position
          buffer[revpos--] = (char) byte;
         
          //get next byte in file in next while loop
          nread--; //decrement # bytes read indicator
     }

     return;
}

Regards, Alex





0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12326661
Note, there is still a bug if your input file has an odd length of characters.

Regards, Alex
0
 
LVL 4

Author Comment

by:daluu
ID: 12330044
Thanks Alex.

I was puzzled there for quite a while. I knew it had to do with the file stream functions but couldn't figure out which one and how. You saved my day.

Based on some reference docs on the web, it said fputc would advance the file pointer by 1 after operation, so I assumed that would move it back automatically. Guess I made the wrong assumption.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now