Solved

reading input file

Posted on 2002-05-18
5
180 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
ID: 7019278
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
ID: 7019280
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
ID: 7019344
is there another method, where I can use getc( fp )???
0
 

Author Comment

by:aagoh
ID: 7019398
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
ID: 7091824
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

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…
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 nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

929 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

10 Experts available now in Live!

Get 1:1 Help Now