Solved

fread/fwrite question

Posted on 2001-08-03
2
620 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Industry Leaders: 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!

Question has a verified solution.

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

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
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.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
Suggested Courses

742 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