Thursday 25 June 2015

C Programming - FILE "rw+" Mode Not Working

Hi!

I have decided to share a project which I created in C language just for some demonstration.

There is a particular scenario addressed in this code, which has to do with overwriting some information in the existing filestream.

In C, you have the syntax as fopen("myfile", "rw+" ) - or "r+w" in other models - to open the file for Read and Write operation then you use the fseek() method to move the file pointer position in file and state the write size to overwrite that record.

However, I discovered that Visual Studio does not allow you to open a file in "rw+" mode and neither does Codeblocks. Probably earlier compilers supported this mode, which I did not experiment.

Should this be the end of the world as far as my project is concerned? Absolutely not!

Find a workaround below - I opened the FILE pointer in "a+" mode and modified the code to refer to the last corresponding record to my test criteria.

Kindly review, share and comment - we all will learn.


#include <stdio.h>
#include <string.h>
#define clrscr() system("cls")
struct customer {
 long no;
 char name[30];
 double bal;
};

struct transaction {
 char type;
 long custno;
 double amount;
 double prvbal;
};

void rectrans() {
 FILE *fp, *fpt;
 long custNumber, size = sizeof(struct customer), sizet = sizeof(struct transaction);
 double custBalance;
 char custName[30];
 struct customer cust;
 struct transaction trnx;
 char flag = 'y', transtype;
 unsigned int recordfound;
 double namount;


 if ((fp = fopen("customer", "a+")) == NULL) {
  printf("\nSorry, server cannot be accessed at this time.\n");
  fclose(fp);
  return;
 }

 if ((fpt = fopen("transaction", "a+")) == NULL) {
  printf("\nSorry, server cannot be accessed at this time.\n");
  fclose(fpt);
  return;
 }
 while (flag == 'y') {
  clrscr();

  recordfound = 0;
  printf("\nEnter customer account number: ");
  scanf(" %ld", &custNumber);

  while ((fread(&cust, size, 1, fp)) != NULL) {
   // set customer Balance and Name to the last matching record.
   if (custNumber == cust.no) {
    recordfound++;
    custBalance = cust.bal;
    strcpy(custName, cust.name);
   }
  }

  if (recordfound < 1) {
   printf("\nInvalid account number.");
  }
  else {
   // Print the customer details
   printf(" %-s \nBalance: %20.2lf\n", custName, custBalance);

   // Request transaction information
   do {
    printf("\nWithdrawal or Deposit? (w/d): ");
    scanf(" %c", &transtype);
    lcase(&transtype);
   } while (transtype != 'w' && transtype != 'd');

   printf("\nEnter transaction amount: ");
   scanf(" %lf", &namount);

   switch (transtype) {
   case 'd':
    printf("\n\Deposit processing ...");

    // preloading transaction data
    trnx.custno = custNumber;
    trnx.prvbal = custBalance;
    trnx.amount = namount;
    trnx.type = 'D';

    // preloading customer data
    cust.bal = custBalance + trnx.amount;
    strcpy(cust.name, custName);
    cust.no = custNumber;

    // write the customer transaction to transaction file
                                // and update customer file
    fseek(fp, -size, SEEK_CUR);
    fwrite(&cust, size, 1, fp);
    fwrite(&trnx, sizet, 1, fpt);
    break;
   case 'w':
    printf("\n\Withdrawal processing ...");
    if ((custBalance - namount) >= 200) {
     // retrieve information relevant for trnx from cust
     trnx.custno = custNumber;
     trnx.prvbal = custBalance;
     trnx.amount = namount;
     trnx.type = 'W';
     cust.bal = custBalance - trnx.amount;
     strcpy(cust.name, custName);
     cust.no = custNumber;

     // write the customer transaction to transaction file
                                        // and update customer file
                                        // (long)(-size) typecast -size to long. 
                                        // fseek() returns position to a struct 
                                        // size backward from the current (1) cursor position.  

     fseek(fp, -size, SEEK_CUR); 
     fwrite(&cust, size, 1, fp);
     fwrite(&trnx, sizet, 1, fpt);
    }
    else {
     printf("\nInsufficient fund in this account.");
    }
    break;
   }
  }

  // rewind customer file fp to start search over for the next account. 
  rewind(fp);
  flag = 'n'; // this line stops the loop.
 }
 // close all fp and fpt
 fclose(fp);
 fclose(fpt);
 return;
}

No comments:

Post a Comment