• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 206
  • Last Modified:

reading input file

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
aagoh
Asked:
aagoh
  • 2
  • 2
1 Solution
 
Peter KwanAnalyst ProgrammerCommented:
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
 
Peter KwanAnalyst ProgrammerCommented:
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
 
aagohAuthor Commented:
is there another method, where I can use getc( fp )???
0
 
aagohAuthor Commented:
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
 
ewestCommented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now