Solved

reading input file

Posted on 2002-05-18
5
177 Views
Last Modified: 2010-04-15
hi all,

I have an input file, regis_info,

registration 1010 file 3 shelf 1 2 copy 1 3
registration 1000 file 2 shelf 1 copy 3
registration 999 file 1 shelf 5 copy 10
registration 888 file 10 shelf 9 copy 18 12
....

and I want to read into a structure,
typedef struct reg_record recs;
struct reg_record {
int reg;
int file
int shelf[10];
int copy[10];
} reg_rec[100];

how do I read the input file into the structure.

I have opened the file with

FILE *fp;
fp = fopen( "regis_info", "r" );

thanks
0
Comment
Question by:aagoh
  • 2
  • 2
5 Comments
 
LVL 16

Expert Comment

by:Peter Kwan
Comment Utility
The following code may help:

int i, j;
char s[100];

fscanf(fp, "registration");

for (i=0; i<100 && !feof(fp); i++) {
   fscanf(fp, "%d ", &(reg_rec[i].reg));
   fscanf(fp, "file %d ", &(reg_rec[i].file));
   fscanf(fp, "shelf %d %s", &(reg_rec[i].shelf[0]), s);
   j=1;
   while (!strcmp(s, "copy")) {
      reg_rec[i].shelf[j]=atoi(s);
      j++;
      fscanf(fp, " %s", s);
   }
   fscanf(fp, "%s", s);
   j=0;
   while (!strcmp(s, "registration") && !feof(fp)) {
      reg_rec[i].copy[j]=atoi(s);
      j++;
      fscanf(fp, "%s", s);
   }
}
0
 
LVL 16

Expert Comment

by:Peter Kwan
Comment Utility
oops... it should be:

int i, j;
char s[100];

fscanf(fp, "registration");

for (i=0; i<100 && !feof(fp); i++) {
  fscanf(fp, "%d ", &(reg_rec[i].reg));
  fscanf(fp, "file %d ", &(reg_rec[i].file));
  fscanf(fp, "shelf %d %s", &(reg_rec[i].shelf[0]), s);
  j=1;
  while (strcmp(s, "copy")) {
     reg_rec[i].shelf[j]=atoi(s);
     j++;
     fscanf(fp, " %s", s);
  }
  fscanf(fp, "%s", s);
  j=0;
  while (strcmp(s, "registration") && !feof(fp)) {
     reg_rec[i].copy[j]=atoi(s);
     j++;
     fscanf(fp, "%s", s);
  }
}
0
 

Author Comment

by:aagoh
Comment Utility
is there another method, where I can use getc( fp )???
0
 

Author Comment

by:aagoh
Comment Utility
and again, is it possible to delimit the structure??
I mean, having the structure without any static limit??
something like this,

ypedef struct reg_record recs;
struct reg_record {
     int reg;
     int file;
     int *shelf;
     int *copy;
     int shelf_held; // holds the max number of shelf
     int copy_held;  // holds the max number of copy
} *reg_rec;

does this structure make any sense??

I am thinking that, of course, after my reading of the file
into the structure is successful, I don't have any static limit to the array of structure.
but for the int *shelf, and int *copy, how do I allocate,
and reallocate memory for that.

thanks in advance.
0
 
LVL 2

Accepted Solution

by:
ewest earned 100 total points
Comment Utility
Use malloc and realloc...

One approach has this general scheme:

Initialize N recs:
        allocate N recs
        max_recs := N
        next_recs := 0
        foreach recs
             allocate S shelf
             shelf_held := S
             shelf_next := 0
             allocate C copy
             copy_held := C
             copy_next := 0

Read in the data:
        rec_count := 0
        while data in file
             if rec_count == max_recs
                   realloc N*2 recs
                   max_recs := N*2
                   foreach recs[N} to recs[max_recs -1]
                       allocate S shelf
                       shelf_held := S
                       shelf_next := 0
                       allocate C copy
                       copy_held := C
                       copy_next := 0
             else if shelf_next == shelf_held
                realloc shelf_held *2
                shelf_held := shelf_held *2
             else if copy_next == copy_held
                realloc copy_held *2
                shelf_held := shelf_held *2

             shelf[shelf_next++] := shelf_data
             copy[copy_next++] := copy_data
             rec_count++    
                shelf[shelf_next++] := shelf_data
             

As a simplified code example of the above:

With input records of the format:

           1 2 3 4
           223 23 23 12 23 12 1 3
           12 1 1 1 2 2 3 4 5



#define INIT_RECCNT 5
#define INIT_NUMCNT 2

typedef struct rec {
    int *num;
    int  numCnt; /* number of num values */
    int  numMax; /* max number of num */
} Rec_t;

Rec_t *recs;
recsCnt;  /* number of records */
recsMax;  /* max number of records */

void *ptr;
char *cptr;
int num;
char buffer[1024];



recs = (Rec_t *)malloc(INIT_RECCNT * sizeof(Rec_t));
recsMax = INIT_RECCNT;
recsCnt = 0;

/* initialize data cache... */
for (i = 0; i < recsCnt; i++) {
    recs[i].num = (int *)malloc(INIT_NUMCNT * sizeof(int));
    recs[i].numMax = INIT_NUMCNT;
    recs[i].numCnt = 0;
}

/* read in data */
while (fgets(buffer, sizeof(buffer), fp))
{
    /* remove newline from string */
    cptr = strrchr(buffer, '\n');
    if (NULL != cptr)
    {
        *cptr = '\0';
    }

    /* sufficient data storage ? */
    if (recsCnt == recsMax)
    {
       ptr = realloc(recs, recsMax *2 * sizeof(Rec_t));
        /* See realloc note */
       if (NULL != ptr)
       {
           recs = (Recs_t *)ptr;
       }
       else
       {
           /* deal with memory error */
       }
       recsMax *=2;

       /* initialize the new memory */
       for (i = 0; i < recsCnt; i++)
       {
          recs[i].num = (int *)malloc(INIT_NUMCNT *                  
                                        sizeof(int));
          recs[i].numMax = INIT_NUMCNT;
          recs[i].numCnt = 0;
        }

     }

     
     /* parse the data */
     ptr = buffer;
     
     while (1)
     {
         num = strtol(ptr, &cptr, 10);
         if (ptr == cptr)
         {
            /* handle error */
            break;
         }

         /* sufficient space for additional num ? */
         if (recs[recsCnt].numCnt == recs[recsCnt].numMax)
         {
              ptr = realloc(recs[recsCnt].num,
                             recs[recsCnt].numMax * 2
                               * sizeof(int));
              /* add some error checking... */

              recs[recsCnt].num = (int *)ptr;
              recs[recsCnt].numMax *= 2;
         }
         recs[recsCnt].num[numCnt++] = num;

         if ('\0' == *cptr)
         {
            /* reached end of input string */
            break;
         }
     }
     recsCnt++;

}

Adapting the above to your problem should be straight-forward. If you have control over the input records, why not include count info in the records stored in the file?

N.B. the sample code is not guaranteed to be bug free...

realloc note 1:
     In the sample code the amount of memory being    
     allocated doubles each time realloc is called.

realloc note 2:
     A general inclination w/ realloc is to assign the
     pointer value returned by the function directly to
     the pointer being realloc'd.

           ptr = realloc(ptr, bytes);

    This is problematic if realloc fails. In this case,  
    NULL is returned and the address to the memory passed
    to the call is lost. This problem is easily addressed
    with the use of a second pointer that is assigned the
    value returned by realloc.

           tmpPtr = realloc(ptr, bytes);

    Now in the event realloc fails and tmpPtr is assigned              
    NULL, the original pointer value is still available.
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

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…
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 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 nested-loops in the C programming language.

772 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

12 Experts available now in Live!

Get 1:1 Help Now