Solved

Read/Write to File

Posted on 2001-08-15
18
293 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
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
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
 

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

Easy, flexible multimedia distribution & control

Coming soon!  Ideal for large-scale A/V applications, ATEN's VM3200 Modular Matrix Switch is an all-in-one solution that simplifies video wall integration. Easily customize display layouts to see what you want, how you want it in 4k.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Test against App 49 138
How do I install gcc 4.8.4 on a Linux Ubuntu 14.04 machine? 5 1,936
C++ vs C compilers 13 160
Constant string is of type char *   ? 7 42
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 how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

809 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