Solved

fread/fwrite question

Posted on 2001-08-03
2
615 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

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

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…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

776 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