Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 627
  • Last Modified:

fread/fwrite question

The question is not hard (to those that know C real well), but I am tired of banging my head against the wall.

I have a very simple handheld application (not for palm) that is having a problem. I took the application and stripped everything out except what I am having a problem with and duplicated it on a DOS machine.

The application asks for item and qty, then writes that out to a file. It lists the information in the file. When the user enters an item number that is already on file, it allows for a change. The problem is it is not saving the change. It goes nowhere.

Below is the code that I can use to duplicate it on the DOS machine.

#include <stdio.h>
#include <string.h>
static struct orders {
     char item_no[21];
     char item_qty[12];
     };

typedef struct orders ORDERS;
FILE *file_ptr;
ORDERS order_rec[1];

main()
{                    
     int idx = 0;
     int rec_cntr;
     char iqty[12];
     char icode[20];

     file_ptr=fopen("ITEMS.DAT","ab+");

     memset(icode,'\0',sizeof(icode));
     memset(iqty,'\0',sizeof(iqty));
     strcpy(order_rec[0].item_no,"ITEM 1");
     strcpy(order_rec[0].item_qty,"10");
     fseek(file_ptr,(long) 0, SEEK_END);
     idx = fwrite(order_rec,sizeof(order_rec[0]),1,file_ptr);
     printf("fwrite = %d\n", idx);

     strcpy(order_rec[0].item_no,"ITEM 2");
     strcpy(order_rec[0].item_qty,"20");
     fseek(file_ptr,(long) 0, SEEK_END);
     idx = fwrite(order_rec,sizeof(order_rec[0]),1,file_ptr);
     printf("fwrite = %d\n", idx);

     strcpy(icode,"ITEM 1");
     idx = find_rec(icode);
     printf("idx for find_rec = %d\n",idx);

     strcpy(iqty,"15");
     strcpy(icode,"UPDATE");
     strcpy(order_rec[0].item_no,icode);
     strcpy(order_rec[0].item_qty,iqty);
     idx = fwrite(order_rec,sizeof(order_rec[0]),1,file_ptr);
     printf("fwrite = %d\n", idx);

     fseek(file_ptr,(long) 0, SEEK_END);
     rec_cntr = ftell(file_ptr) / sizeof(order_rec[0]);
     fseek(file_ptr,(long) 0, SEEK_SET);
     idx = 0;
     while (idx < rec_cntr)
     {
          fseek(file_ptr,(long) idx*sizeof(order_rec[0]),SEEK_SET);
          fread(order_rec,sizeof(order_rec[0]),1,file_ptr);
          printf("item = %s, qty = %s\n",order_rec[0].item_no,order_rec[0].item_qty);
          idx++;
     }
}

static int find_rec(icode)
     char icode[21];
{
     int idx, rec_cntr;
     idx = 0;
     fseek(file_ptr,(long) 0, SEEK_END);
     rec_cntr = ftell(file_ptr) / sizeof(order_rec[0]);
     if (rec_cntr == 0)
     {
          return(-2);
     }
   
     fseek(file_ptr,(long) 0, SEEK_SET);
     while (idx < rec_cntr)
     {
          fseek(file_ptr,(long) idx*sizeof(order_rec[0]),SEEK_SET);
          fread(order_rec,sizeof(order_rec[0]),1,file_ptr);
          if (strcmp(order_rec[0].item_no, icode) == 0)
          {
               return(idx);
          }
          idx++;
     }
     fseek(file_ptr,(long) 0, SEEK_END);
     return(-1);
}

I hope someone can help me. I am at a loss.
Thanks
0
dchorton
Asked:
dchorton
1 Solution
 
NeelimaCommented:
dchorton,
  you are opening the file in an append mode and then expect it to overwrite the previous data!!

0
 
LockiasCommented:
OK, here is the deal.  When you are adding items you can open the file with an "a" flag, which is for appending.  EVERYTHING you write will go on the end, so your seeks to the end are not necessary.  Also, the "a" will create the file if it does not exist.

Now, when you go to make the update you need to able to read and write.  Therefore open the file with the "r+" flag.  Note that "w+" would create the file if it did not exist, but it also kills the contents of what you open (not what you want!).  If you want to open the file read write and ensure that it is created, you will need to use _open(filename, _O_RDWR | _O_CREAT).  Anyway, in your program you need to close the file opened with "a", and then open it with "r+".  Or if you know the file exists you can use "r+" from the beginning (or you use _open like I said).  Then you just need to make sure to use fflush in between reads and writes.

Now, with that said, after you call find_rec and before you write the update you need to seek the file to the correct spot to write.  The position changes in your find_rec routine.  So the block
    strcpy(iqty,"15");
    strcpy(icode,"UPDATE");
    strcpy(order_rec[0].item_no,icode);
    strcpy(order_rec[0].item_qty,iqty);
    idx = fwrite(order_rec,sizeof(order_rec[0]),1,file_ptr);

should be

    strcpy(iqty,"15");
    strcpy(icode,"UPDATE");
    strcpy(order_rec[0].item_no,icode);
    strcpy(order_rec[0].item_qty,iqty);
    fseek(file_ptr,(long) idx*sizeof(order_rec[0]),SEEK_SET);
    idx = fwrite(order_rec,sizeof(order_rec[0]),1,file_ptr);


So with all of that said, here is a final copy of the program that works:

------------------------------------------------------
#include <stdio.h>
#include <string.h>
static struct orders {
    char item_no[21];
    char item_qty[12];
    };

typedef struct orders ORDERS;
FILE *file_ptr;
ORDERS order_rec[1];

main()
{                    
    int idx = 0;
    int rec_cntr;
    char iqty[12];
    char icode[20];

    file_ptr=fopen("ITEMS.txt","ab+");

    memset(icode,'\0',sizeof(icode));
    memset(iqty,'\0',sizeof(iqty));
    strcpy(order_rec[0].item_no,"ITEM 1");
    strcpy(order_rec[0].item_qty,"10");
    fseek(file_ptr,(long) 0, SEEK_END);
    idx = fwrite(order_rec,sizeof(order_rec[0]),1,file_ptr);
    printf("fwrite = %d\n", idx);

    strcpy(order_rec[0].item_no,"ITEM 2");
    strcpy(order_rec[0].item_qty,"20");
    fseek(file_ptr,(long) 0, SEEK_END);
    idx = fwrite(order_rec,sizeof(order_rec[0]),1,file_ptr);
    printf("fwrite = %d\n", idx);
    fclose(file_ptr);

    file_ptr= fopen("ITEMS.txt", "r+");

    strcpy(icode,"ITEM 1");
    idx = find_rec(icode);
    printf("idx for find_rec = %d\n",idx);

    strcpy(iqty,"15");
    strcpy(icode,"UPDATE");
    strcpy(order_rec[0].item_no,icode);
    strcpy(order_rec[0].item_qty,iqty);
    fseek(file_ptr,(long) idx*sizeof(order_rec[0]),SEEK_SET);
    idx = fwrite(order_rec,sizeof(order_rec[0]),1,file_ptr);
    printf("fwrite = %d\n", idx);

    fseek(file_ptr,(long) 0, SEEK_END);
    rec_cntr = ftell(file_ptr) / sizeof(order_rec[0]);
    fseek(file_ptr,(long) 0, SEEK_SET);
    idx = 0;
    while (idx < rec_cntr)
    {
         fseek(file_ptr,(long) idx*sizeof(order_rec[0]),SEEK_SET);
         fread(order_rec,sizeof(order_rec[0]),1,file_ptr);
         printf("item = %s, qty = %s\n",order_rec[0].item_no,order_rec[0].item_qty);
         idx++;
    }
}

static int find_rec(icode)
    char icode[21];
{
    int idx, rec_cntr;
    idx = 0;
    fseek(file_ptr,(long) 0, SEEK_END);
    rec_cntr = ftell(file_ptr) / sizeof(order_rec[0]);
    if (rec_cntr == 0)
    {
         return(-2);
    }
   
    fseek(file_ptr,(long) 0, SEEK_SET);
    while (idx < rec_cntr)
    {
         fseek(file_ptr,(long) idx*sizeof(order_rec[0]),SEEK_SET);
         fread(order_rec,sizeof(order_rec[0]),1,file_ptr);
         if (strcmp(order_rec[0].item_no, icode) == 0)
         {
              return(idx);
         }
         idx++;
    }
    fseek(file_ptr,(long) 0, SEEK_END);
    return(-1);
}
------------------------------------------------------

~Lockias


0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now