Solved

Read from a file

Posted on 2004-04-19
5
261 Views
Last Modified: 2010-04-15
Hi,

I am reading my data structure from my c program instead I would like to read my datastructure from a file.

Here is my program

//------------------------------------------------------------------
#include <stdio.h>

int main()
{
  FILE *infile;
  FILE *outfile;
  struct
  {
    char value1[2];
    char emty1[14];
    char value4[4];
    char value7[4];
    char empty2[8];
    int  key;
    char empty3[14];
  } mytype;

  infile=fopen("Datafile","rb");
  outfile=fopen("Outfile","wb");
  while(!feof(infile))
  {
    fread(&mytype,sizeof(mytype),1,infile);
    if(!feof(infile))
    {
     if(mytype.key==30069)
     {
      fprintf(outfile,"1st value = \'%\'\n",mytype.value1);
      fprintf(outfile,"4th value = \'%\'\n",mytype.value4);
      fprintf(outfile,"7th value = \'%\'\n",mytype.value7);
     }
    }
  }
  fclose(outfile);
  fclose(infile);
  return(0);
}
//------------------------------------


This structure,
struct
  {
    char value1[2];
    char emty1[14];
    char value4[4];
    char value7[4];
    char empty2[8];
    int  key;
    char empty3[14];
  } mytype;

I would like to read from a file (e.g. structure.txt). How would I do that?

I will be really appreciate your help.

Thanks,
John.
 
0
Comment
Question by:John22
  • 2
5 Comments
 
LVL 45

Expert Comment

by:Kdo
ID: 10861427
Hi John22,

You'd do it almost exactly like you're doing now.   The catch is that the text file must have the data in the exact format (spacing) as your structure expects.

To get a good sample, initialize the items of your structure with fixed data and write it to your output file.

 
#include <stdio.h>

/*  The struct definition is global, so move it outside of main()  */
/*  Also, using 'typedef struct' instead of just 'struct' can make usage a bit easier  */

  typedef struct
  {
    char value1[2];
    char emty1[14];
    char value4[4];
    char value7[4];
    char empty2[8];
    int  key;
    char empty3[14];
  } mytype;


int main()
{
  FILE    *infile;
  FILE    *outfile;
  mytype  mydata;    /* mytype structure */

  infile=fopen("Datafile","rb");
  outfile=fopen("Outfile","wb");
  while(!feof(infile))
  {
    fread(&mydata,sizeof(mytype),1,infile);
    if(!feof(infile))
    {
     if(mytype.key==30069)
     {
      fprintf(outfile,"1st value = \'%\'\n",mytype.value1);
      fprintf(outfile,"4th value = \'%\'\n",mytype.value4);
      fprintf(outfile,"7th value = \'%\'\n",mytype.value7);
     }
    }
  }
  fclose(outfile);
  fclose(infile);
  return(0);
}



Good Luck,
Kent
0
 

Author Comment

by:John22
ID: 10861608
Hi Kent,

Thanks for your reply.

May be, I wasn't clear in my description.

The below structure, I would like to read from a file (structure.txt) instead of my C program.

 typedef struct
  {
    char value1[2];
    char emty1[14];
    char value4[4];
    char value7[4];
    char empty2[8];
    int  key;
    char empty3[14];
  } mytype;

I am also reading another binary file (Datafile). It will be two files, one binary file (Datafile) and another structure file (structure.txt).

The purpose of this thing is : I am going to compile my c program and use executable. So, Whenever I use different Datafile binary file, I just need to modify structure.txt file. I don't have recompile my code.

Thanks.
0
 
LVL 45

Accepted Solution

by:
Kdo earned 50 total points
ID: 10861703
Hi John,

It's not so easy as that.  When you compile a program, the structure becomes an integral part of your program.  If you want to make a data structure that can change according to a parameter file, or as in your stated case a "structure" file, you need to do all of the heavy lifting yourself.  This means that your structure file will have to be kept in a format that your program can understand, and you'll have to do all of the data manipulation based on character positioning.  Your code won't be able to maintain the structure by using normal structure syntax.

I'll be glad to show you how it's done, but it really is a lot of work and makes for a lot more complicated code than just recompiling an existing program.

Kent
0
 
LVL 10

Expert Comment

by:Mercantilum
ID: 10861968
I propose you this syntax for your structure.txt file:
 1 char for type ((C)har, (I)nt, (D)ouble...)
 n chars for the "number of" times of type
 '\n'

----For your structure you would have in the file
C2
C14
C4
C4
C8
I1
C14
----

You create a function to read the structure, and set three (allocated) arrays, char types[], int lengths[], int isize[], and an int 'items' (number of items)
lengths for arrays is the number of elements, isize is the size in bytes of all elements
And you calculate the size of the structure int ssize at the same time.
items = ssize = 0;
...
while (fgets (buf, 10, file_struct))
{
   if (buf[0] == 'C' || buf[0] == 'I' || buf[0] == 'D')
   {
      types[items]  = *buf;
      lengths[items] = atoi(buf+1);
      isize[items]   = lengths[items] * (*buf=='C' ? sizeof(char):(*buf =='I' ? sizeof(int):sizeof(double)));
      ssize += isize[items];
      items++;
   }
}


Now you have your three vars set, you can deal with the actual data file (example)
for one struct  (BYTE is unsigned char)

    int h = open ("datafile", O_RDONLY); // open file you could use fopen
    BYTE *my_data = malloc(ssize);
    read (h, my_data, ssize);  // 1 struct is read (errors to be checked)


The almost last part is to access the items of the struct ... we can imagine a function returning the nth item in a buffer (preallocated), type and
indicate the number of times (array), one or more... We use here my_data previously filled with one struct from data file

BYTE *getitem (int num, char *type, int *elements)
{
    int i, offset;
    for (offset=i=0 ; i<num ; i++) offset += isize[i]; // calculate offset of requested item
    *type = types[num];
    *elements = lengths[num];
    return ((BYTE *)my_data + offset);
}


And finally an example to print all items... (from my_data)
...
   BYTE *one;
   char type;
   int nelem;
   int i,j;

   for (i=0 ; i<items ; i++)
   {
      one = getitem (i, &type, &nelem);
      for (j=0 ; j<nelem ; j++)   switch (type)
      {
      case 'C': printf ("%c", one + j*sizeof(char)) ; break;
      case 'I': printf ("%d", one + j*sizeof(int)) ; break;
      case 'D': printf ("%lf", one + j*sizeof(double)) ; break;
      default:
   }
   printf ("\n");

This can be optimized but it can be a good start.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
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 structures in the C programming language.

707 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

15 Experts available now in Live!

Get 1:1 Help Now