Solved

fread/fwrite question

Posted on 2001-08-03
2
607 Views
Last Modified: 2008-03-10
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
Comment
Question by:dchorton
2 Comments
 

Expert Comment

by:Neelima
ID: 6348474
dchorton,
  you are opening the file in an append mode and then expect it to overwrite the previous data!!

0
 
LVL 2

Accepted Solution

by:
Lockias earned 200 total points
ID: 6349090
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

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

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

705 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

12 Experts available now in Live!

Get 1:1 Help Now