[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

fread/fwrite question

Posted on 2001-08-03
2
Medium Priority
?
626 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 800 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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

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…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
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

656 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