Hi all,

I have a code to read the records using a file,also the file has got unnecessary stuff that needs to be ignored.
I am able to read and write only the first record,next am able to read and write only the second "record name" but not the whole record.

Pls help me out to get the desired result.
I am using unix machine/putty to run the code.

Also,pls check the csp.txt file attached.

Regards,
Srikanth.

This is my code::

#include<stdio.h>
#include<string.h>
void fetch_word();


struct rec_name
{
char name[10];
}rec[2];

char arr[120]={0};
char *arr1;
FILE *fp;
char *substring(size_t start, size_t stop, const char *src, char *dst, size_t size)
{
   int count = stop - start;
   if ( count >= --size )
   {
      count = size;
   }
   sprintf(dst, "%.*s", count, src + start);
   return dst;
}
int main()
{
char ch,p[10];
int i=0,x,m;
#define MAX 120
char buff[MAX];
arr1=(char *)malloc(sizeof(char)*150);
        fp=fopen("csp.txt","r");
while(!feof(fp))
{
        fgets(buff,MAX,fp);
        if(strstr(buff,"RECORD NAME:")!=NULL)
        {

                for(i=1;i<2;i++)
                {
                substring(65, 75, buff,p,sizeof(p));
                strcpy(rec[i].name,p);
                printf("RECD NAME::%s\n",rec[i].name);
      
                }
        }


        if( ((strstr(buff,"DESCRIPTION"))!=NULL)  )
        {
        printf("INTO THE RECORDS NOW:");
                while(strstr(arr,"RECORD DEFINITIONS")==NULL)
                {
                fgets(arr,120,fp);
                printf("\n%s",arr);
                }
        }

}

fclose(fp);

}
Attachments
#include<stdio.h>
#include<string.h>
void fetch_word();


struct rec_name
{
char name[10];
}rec[2];

char arr[120]={0};
char *arr1;
FILE *fp;
char *substring(size_t start, size_t stop, const char *src, char *dst, size_t size)
{
   int count = stop - start;
   if ( count >= --size )
   {
      count = size;
   }
   sprintf(dst, "%.*s", count, src + start);
   return dst;
}
int main()
{
char ch,p[10];
int i=0,x,m;
#define MAX 120
char buff[MAX];
arr1=(char *)malloc(sizeof(char)*150);
        fp=fopen("csp.txt","r");
while(!feof(fp))
{
        fgets(buff,MAX,fp);
        if(strstr(buff,"RECORD NAME:")!=NULL)
        {

                for(i=1;i<2;i++)
                {
                substring(65, 75, buff,p,sizeof(p));
                strcpy(rec[i].name,p);
                printf("RECD NAME::%s\n",rec[i].name);
      
                }
        }


        if( ((strstr(buff,"DESCRIPTION"))!=NULL)  )
        {
        printf("INTO THE RECORDS NOW:");
                while(strstr(arr,"RECORD DEFINITIONS")==NULL)
                {
                fgets(arr,120,fp);
                printf("\n%s",arr);
                }
        }

}

fclose(fp);

}
RECORD DEFINITIONS
0                                  RECORD NAME:                  ZZYA6C1
0                                  ORGANIZATION:                 ORKING STORAGE
                                   LENGTH IN BYTES:              752
                                   DEFAULT SCOPE:                GLOBAL
                                   MSL:                          ROMSL2
0
0       PROLOGUE
                                   HTLN Common/Inter-screen Work Record
                                   *----------------------------------------------------------*
                                   *           M O D I F I C A T I O N    L O G               *
                                   *--------------------------------------------------------- *
                                   * Date        Modified By     Description of Change        *
                                   *--------------------------------------------------------- *
                                   * 07/09/2002  Balaji          Added new fields             *
                                   *             Venkataraman    (Refer Document MZD002-011)  *
                                   *----------------------------------------------------------*
                                   * 10/30/2002  Ramprasadh V    Added new fields             *
                                   *                             (Refer Document MZD009-010)  *
                                   *----------------------------------------------------------*
                                   *----------------------------------------------------------*
                                   * 02/08/2008  CGS          Replaced field PRSNIDCD         *
                                   *                             with DLRWSL and *            *
                                   *----------------------------------------------------------*
0NAME                             LVL OCCURS TYPE SCOPE LENGTH DEC  BYTES  START    MSL    DESCRIPTION
0YA6PRMDG                         05         CHA  GLOBAL   752        752      1  ROMSL2   HTLN primary area
0YA6CRIDG                         10         CHA  GLOBAL   173        173      1  ROMSL2   HTLN Primary Criteria
0HTREFCD                          15         BIN  GLOBAL     9          4      1  ROMSL2   HTLN_REF_CD
0VINCD                            15         CHA  GLOBAL    17         17      5  ROMSL2   VIN CODE


RECORD DEFINITIONS
0                                  RECORD NAME:                  ZZYA6C2
0                                  ORGANIZATION:                 ORKING STORAGE
                                   LENGTH IN BYTES:              752
                                   DEFAULT SCOPE:                GLOBAL
                                   MSL:                          ROMSL2
0
0       PROLOGUE
                                   HTLN Common/Inter-screen Work Record
                                   *----------------------------------------------------------*
                                   *           M O D I F I C A T I O N    L O G               *
                                   *--------------------------------------------------------- *
                                   * Date        Modified By     Description of Change        *
                                   *--------------------------------------------------------- *
                                   * 07/09/2002  Balaji          Added new fields             *
                                   *             Venkataraman    (Refer Document MZD002-011)  *
                                   *----------------------------------------------------------*
                                   * 10/30/2002  Ramprasadh V    Added new fields             *
                                   *                             (Refer Document MZD009-010)  *
                                   *----------------------------------------------------------*
                                   *----------------------------------------------------------*
                                   * 02/08/2008  CGI          Replaced field PRSNIDCD         *
                                   *                             with DLRWSL and *            *
                                   *----------------------------------------------------------*
0NAME                             LVL OCCURS TYPE SCOPE LENGTH DEC  BYTES  START    MSL    DESCRIPTION
0KA6PRMDG2                         06         CHA  GLOBAL   752        752      1  ROMSL2   HTLN primary area
0BA6CRIDG2                         10         CHA  GLOBAL   173        173      1  ROMSL2   HTLN Primary Criteria
0CTREFCD2                          15         BIN  GLOBAL     9          4      1  ROMSL2   HTLN_REF_CD
0AINCD2                            15         CHA  GLOBAL    17         17      5  ROMSL2   VIN CODE

you're getting stuck on the while loop:

while(strstr(arr,"RECORD DEFINITIONS")==NULL)
{
fgets(arr,120,fp);
printf("\n%s",arr);
}

Nothing in the main while(!feof(fp)) ever resets the value in arr. So when you get to the second record's data you print 'INTO THE RECORDS NOW' but don't ever actually read any data because arr still contains 'RECORD DEFINITIONS'

When you fix that, you're going to have a problem when you're reading the last record in the file (if your file is like the file you attached). The last record does not have a 'RECORD DEFINITIONS' after it to close the while loop. You should probably either add a test for eof() to the while, or test for eof() inside the while and use break to stop.

The other way I've written similar parsers in the past is to use a 'parse state' variable. For your example, your parse states would be something like LOOKING_FOR_RECORD, LOOKING_FOR_DETAIL, IN_DETAIL

So pseudo code for the parser would look something like:

#define LOOKING_FOR_RECORD 1
#define LOOKING_FOR_DETAIL 2
#define IN_DETAIL 3
int pstate = LOOKING_FOR_RECORD;
while(!feof(fp))
{
    fgets(buff,MAX,fp);
    
    switch (pstate)
    {
        case LOOKING_FOR_RECORD:
            if (strstr(buff, "RECORD NAME:") != NULL)
            {
                // Do Record Name handling here
                pstate = LOOKING_FOR_DETAIL;
            }
            break;
        case LOOKING_FOR_DETAIL:
            if (strstr(buff, "DESCRIPTION") != NULL)
                pstate = IN_DETAIL;
            break;
        case IN_DETAIL:
            // from your sample file, you could also stop IN_DETAIL when you encounter an empty line
            if (strstr(buff, "RECORD DEFINITIONS") != NULL)
                pstate = LOOKING_FOR_RECORD;
            else
            {
                // Do Detail Record Handling Here
            }
            break;
    }
}
This article has been dead for over six months. Start a new discussion instead.