Solved

Read/Write to File

Posted on 2001-08-15
18
280 Views
Last Modified: 2010-04-15
Attempting to Read and write data from a structure to file.

Think the write part is ok since the file contains data when I open it.

The read part however fails miserably; This is what I got:

FILE *fp=fopen("File.dat","rb");
struct Mystruct *start;

start=(struct Mystruct*)malloc(sizeof(struct Mystruct));

while(!feof)
{
    fread(start,sizeof(struct Mystruct),1,fp);
}
fclose(fp);

0
Comment
Question by:kapai
  • 5
  • 5
  • 4
  • +4
18 Comments
 
LVL 6

Expert Comment

by:Triskelion
ID: 6387736
Try fread (&start, ...,...,...);


Actually, I prefer to do away with the struct thing by using a typedef up front

typedef struct tagSTART
{
   char strStuff[15];
   char strMoreStuff[15];
} START;

then

static START start;

fread (&start, sizeof(start), 1, fp);
0
 
LVL 6

Expert Comment

by:Triskelion
ID: 6387752
Here's a sample from another question that uses the technique I mentioned.
I reverse the size and count parameters on the fread to cover a situation where the file may not be properly built or an extra carriage return/linefeed.

typedef struct tagSTOCK_DATA
{
  char strTimeField[8];
  char strStockName[20];
  char chrYesNoFlag;
  char strStartValue[8];
  char strEndValue[8];
  char strCR_LF[2]; //Carriage return / Line feed
} STOCK_DATA;


bool DoSomeProcess(STOCK_DATA * pstkData);

int main(int argc, char ** argv)
{
     auto          FILE     *          hanInputFile=NULL;
     auto          FILE     *          hanOutputFile=NULL;
     static     STOCK_DATA     stkMyStock;
     
     if (argc < 3)
          {
          puts ("Usage program {filename.dat} {outfile.dat}");
          return     1;
          }

     if (NULL == (hanInputFile=fopen(argv[1], "rb")))
          {
          puts("Cannot open input file");
          return     2;
          }

     if (NULL == (hanOutputFile=fopen(argv[2], "wb")))
          {
          puts("Cannot create output file");
          fclose(hanInputFile);
          return     3;
          }

     fread(&stkMyStock, 1, sizeof(stkMyStock), hanInputFile);

     while (!feof(hanInputFile))
          {
          DoSomeProcess(&stkMyStock);
          fread(&stkMyStock, 1, sizeof(stkMyStock), hanInputFile);
          }

     fclose(hanOutputFile);
     fclose(hanInputFile);
     return     0;
}

bool DoSomeProcess(STOCK_DATA * pstkData)
{
     if (!pstkData)
          {
          return false;
          }

     // ... do dome processing here ...

     return true;
}
0
 
LVL 86

Expert Comment

by:jkr
ID: 6387913
>>The read part however fails miserably

HOW does it fail?

BTW,

while(!feof)

should read

while(!feof(fp))
0
 
LVL 6

Expert Comment

by:Triskelion
ID: 6388678
What is the 'MyStruct' structure?
You may not need to malloc it unless you're concerned about memory.
0
 

Author Comment

by:kapai
ID: 6392114
Can't use typedef thing but will keep it in mind.
Reads and then displays first record then crashes.
Perhaps read part is correct and error is in write part.
Can anyone suggest code to do both??
Must be from a struct data type.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6394662
Try the following code:

FILE *fp=fopen("File.dat","rb");
struct Mystruct start;

while(!feof(fp))
{
   fread(&start,sizeof(struct Mystruct),1,fp);
}
fclose(fp);

0
 

Author Comment

by:kapai
ID: 6396384
oops forgot to mention its a single linked list
0
 

Expert Comment

by:prabhuram
ID: 6396611
I think, this code 'll give you one of the options to do your req:
try this out if you have enough patience.

main()
{
 FILE *fp = fopen("datas","rb");
 struct NODE n;
 int count = fread(&n,sizeof(n),1,fp);
 while(count)
 {
 printf("%d %s\n",n.value,n.name);
 count=fread(&n,sizeof(n),1,fp);
 }
}

its working, right?
bye,
prabhuram
prabhu_ram_99@yahoo.com
0
 
LVL 6

Expert Comment

by:Triskelion
ID: 6396799
Can you post the MyStruct structure?
This could be solved in seconds.
0
ScreenConnect 6.0 Free Trial

Explore all the enhancements in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

 

Author Comment

by:kapai
ID: 6399462
struct Parts
{
     char PartNum[5];
     char SupplyName[24];
     int Quantity;
     char ProdDesc[24];
     float WsalePrice;
     float RetPrice;
     struct Parts *next;
}*newnode, *ptr3, *prev3, *start3;
0
 
LVL 6

Expert Comment

by:kotan
ID: 6399729
How do you implement your write part?

I think you have done a mistake in the write part. when you call fwrite() to store the struct Parts, It only stores the memory address of start->next which is 2 bytes not the whole structure it point to.

then what you get in the read part for the member next is only the address it stored.

What you can do is insert one by one to record to the file and read one by one in read part as well.

If you want I can write both write part and read part code for you.
0
 
LVL 6

Expert Comment

by:kotan
ID: 6399777
Writing part,

   struct Part *start;
   struct Part *instart = start;

   while (instart != NULL)
   {
      fwrite(instart, sizeof(struct Parts), 1, fp);
      instart = instart->next;
   }
   
reading part,

   struct Part *start;
   struct Part *instart = start;

   while (!feof(fp))
   {
      instart = (struct Part *) malloc(sizeof(struct Part));
      fread(instart, sizeof(struct Parts), 1, fp);
      instart = instart->next;
   }

Hope this helps.

Best Regard,
kotan
0
 

Author Comment

by:kapai
ID: 6399778
please do, played around with code so much now neither works.
0
 
LVL 6

Expert Comment

by:kotan
ID: 6399838
Sorry! Have some modification on reading part. Please ignore previous one.

  struct Part *start;
  struct Part *instart, *prevstart;

  start = (struct Parts *) malloc(sizeof(struct Part));
  instart = start;

  while (!feof(cfPtr))
  {
         fread(instart, sizeof(struct Parts), 1, cfPtr);
         prevstart = instart;
         instart->next = (struct Parts *) malloc(sizeof(struct Parts));
         instart = instart->next;
  }

  if (prevstart != NULL)
  {
     prevstart->next = NULL;
  }
  free(instart); // Free last node which contains no data
0
 
LVL 2

Expert Comment

by:VCStud
ID: 6399965
Just a hunch... hope it works.
Did you try using fseek to move the file pointer to the start after opening the file in read mode?

fseek(fp, 0, SEEK_SET);

Cheers,
VCStud

0
 
LVL 6

Accepted Solution

by:
kotan earned 300 total points
ID: 6399966
Sorry again! The reading part code for the previous one got pitfall.
Below is the perfect one.

      start = (struct Parts *) malloc(sizeof(struct Parts));
      instart = start;

      while (!feof(cfPtr))
      {
         fread(instart, sizeof(struct Parts), 1, cfPtr);
         printf("%p %d\n", instart->next, instart->Quantity);

         if (instart->next == NULL)
         {
            break;
         }

         instart->next = (struct Parts *) malloc(sizeof(struct Parts));
         instart = instart->next;
      }

FYI, You must make sure that the variable next of the last node should be point to NULL. If not, both method I provided won't work.
0
 
LVL 6

Expert Comment

by:Triskelion
ID: 6401250
Here is an example of the definition, creation, population, writing and reading of the PARTS structure.

Yes an array of linked list items is redundant, I'm just lazy (sorta);  In actuality, you could use the array instead of the linked list.  You'd just have to know how many records you're going to have.

Are you required to use malloc?

If so, then I can cook an example that uses malloc.

Run this through the debugger to see it work.
It also handles the addressing of the next in the link.

#include <stdio.h>
#include <string.h>

#define     MAX_NODES     (short)     2

typedef struct tagPARTS
{
     char          PartNum[5];
     char          SupplyName[24];
     int          Quantity;
     char          ProdDesc[24];
     float          WsalePrice;
     float          RetPrice;
     struct     tagPARTS *next;
} PARTS;

int main(void)
{
     static     PARTS newnode[MAX_NODES];     // not a pointer
     static     PARTS     nodeGeneric;
     auto          int     intLoop=0;
     /*
     PARTS     *     ptr3;
     PARTS     *     prev3;
     PARTS     *     start3;
     */
     FILE     *     hanInputFile=NULL;
     FILE     *     hanOutputFile=NULL;

     if (NULL==(hanOutputFile=fopen("20168749.dat", "wb")))
          {
          puts("Cannot Open Output File");
          return 1;
          }

     memcpy(nodeGeneric.PartNum, "0000", sizeof(nodeGeneric.PartNum));
     memcpy(nodeGeneric.SupplyName, "Reece's PB Cups", sizeof(nodeGeneric.SupplyName));
     nodeGeneric.Quantity=1;
     memcpy(nodeGeneric.ProdDesc, "Worlds Best Candy", sizeof(nodeGeneric.ProdDesc));
     nodeGeneric.WsalePrice=(float)0.23;
     nodeGeneric.RetPrice=(float)0.65;
     nodeGeneric.next=NULL;

     // write something to file
     fwrite (&nodeGeneric, sizeof(PARTS), 1, hanOutputFile);

     memcpy(nodeGeneric.PartNum, "0001", sizeof(nodeGeneric.PartNum));
     memcpy(nodeGeneric.SupplyName, "Reece's Nutrageous", sizeof(nodeGeneric.SupplyName));
     nodeGeneric.Quantity=1;
     memcpy(nodeGeneric.ProdDesc, "2nd Best Candy", sizeof(nodeGeneric.ProdDesc));
     nodeGeneric.WsalePrice=(float)0.23;
     nodeGeneric.RetPrice=(float)0.65;
     nodeGeneric.next=NULL;

     // write someting to file
     fwrite (&nodeGeneric, sizeof(PARTS), 1, hanOutputFile);

     fclose(hanOutputFile);

     if (NULL==(hanInputFile=fopen("20168749.dat", "rb")))
          {
          puts("Cannot Open Input File");
          return 2;
          }

     intLoop=0;
     // Watch this run in the debugger step by step
     while(!feof(hanInputFile) && (intLoop < MAX_NODES))
          {
          fread(&newnode[intLoop], sizeof(PARTS), 1, hanInputFile);
          if (intLoop > 0)
               {
               // Link the list and increment the loop counter;
               newnode[intLoop - 1].next = &newnode[intLoop];
               }
          intLoop++;
          }
     
     fclose(hanInputFile);
     return     0;
}

0
 

Author Comment

by:kapai
ID: 6401897
Thanks to all who contributed, especially tristelion, I'm sure his code would have worked but uses stuff over my head.
Kotan has addressed my problem exactly thanks again.
0

Featured Post

Are your corporate email signatures appalling?

Is it scary how unprofessional your email signatures look? Do users create their own terrible designs and give themselves stupid job titles? You can make this a lot easier for yourself by choosing an email signature management solution from Exclaimer today.

Question has a verified solution.

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

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…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

919 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

16 Experts available now in Live!

Get 1:1 Help Now