Solved

need help finding bug in buffer to file swap program

Posted on 2004-10-15
5
270 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
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…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

756 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