Solved

Read/Write to File

Posted on 2001-08-15
18
279 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
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

 

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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
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 and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

757 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

18 Experts available now in Live!

Get 1:1 Help Now