Solved

Read from a file

Posted on 2004-04-19
5
272 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
[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
5 Comments
 
LVL 45

Expert Comment

by:Kent Olsen
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:
Kent Olsen 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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

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…
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…
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.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

756 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