Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

need help finding bug in buffer to file swap program

Posted on 2004-10-15
5
Medium Priority
?
274 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 1000 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: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying 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

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
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.
Suggested Courses

916 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