Killroy edit that post and leave only the necessary code. That's HUGE!!!! Noone will even look at it
Killroy edit that post and leave only the necessary code. That's HUGE!!!! Noone will even look at it
You're over complicating your read process. Why don't you use the method I've suggested?
Also, are you checking to make sure malloc hasn't failed?Code:char buf[BUFSIZ]; char *ptr; while( fgets( buf, BUFSIZ, inputfile ) != NULL ) /* read a line from file */ { if( (ptr = strstr( buf, "xx." ) != NULL ) /* if the line contains 'xx.' */ { ptr += 3; /* skip past 'xx.' */ /* now do something with this line. use 'ptr' to sscanf from or whatever, * as we have already skipped past the 'xx.' portion. */ } }
Furthermore, you never need to typecast the return value of malloc or realloc in C.
Finally, you should be checking the return value of your sscanf call to makes sure it's actually scanning the right amount of items in.
Try working from there.
Quzah.
Hope is the first step on the road to disappointment.
Well it seems to me that all your cases do exactly the same thing, except for one line
Behold the power of common code and indentation
This prints the followingCode:#include <string.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <unistd.h> #include <math.h> #define MAX_LINE (128+1) /* Maximum length of a source line plus one */ #define CM_NAME_LENGTH 20 /* an enumeration is better that a whole bunch of #defines */ enum { CM_CF = 1, CM_CF_CA, CM_WF_Shield, CM_Comma, CM_Lee_Cld }; typedef struct { char Name[CM_NAME_LENGTH]; int Value; } NameDefinition_t; typedef struct { int Index; int X; /* Longitude */ int Y; /* Latitude */ char Direction; /* Direction, East or West */ int CommentLines; /* Number of infolines */ char **Comments; } NameDescription_t; NameDefinition_t CM_lijst[] = { {"CF", CM_CF}, {"CF in CA", CM_CF_CA}, {"WF Shield", CM_WF_Shield}, {"Comma", CM_Comma}, {"Lee Cloud", CM_Lee_Cld}, {"", 0} }; /* Open Structure to write XML file*/ typedef struct WRITER { float lat; float lon; char CM[50]; char info[2000]; char dir; int cl; } WRITE; WRITE *StrXML; NameDescription_t *NameDescriptions = NULL; /* ************* Function ************************* */ /* searches the name definitions and returns the associated value */ int FindNameValue(char *Name) { int i; for (i = 0; *CM_lijst[i].Name; i++) if (strcmp(Name, CM_lijst[i].Name) == 0) return (CM_lijst[i].Value); return (0); } /* ************ Start of main ********************* */ int main() { NameDescription_t *Name; char InputBuffer[MAX_LINE]; char StartJunk[5], NameString[CM_NAME_LENGTH]; int X1, X2, X3; int Y1, Y2, Y3; int idx, n, k; char C1, C2, C3; FILE *STRPfile; idx = 0; n = 0; k = 0; /* Allocate memory to later write XML file*/ StrXML = malloc(256 * 256 * sizeof *StrXML ); if ((STRPfile = fopen("test.txt", "r")) == NULL) { fprintf(stderr, "Error opening info-file :%s\n", "test.txt"); exit(1); } for (idx = 0; idx <= 2; idx++) { fgets(InputBuffer, MAX_LINE, STRPfile); } while (fgets(InputBuffer, MAX_LINE, STRPfile)) { /* your %s to read the command would not cope with spaces */ /* %[^:] is like %s, but it takes everything which isn't a : */ sscanf(InputBuffer, "%4s %[^:]: %2d%2d%c (%2d%2d%c - %2d%2d%c)", StartJunk, NameString, &X1, &Y1, &C1, &X2, &Y2, &C2, &X3, &Y3, &C3); printf( "Name='%s'\n", NameString ); Name = malloc(sizeof *Name); memset(Name, 0, sizeof *Name ); Name->Index = FindNameValue(NameString); Name->X = X1; Name->Y = Y1; Name->Direction = C1; /* descriptions end with a blank line in the file */ while (fgets(InputBuffer, MAX_LINE, STRPfile) && InputBuffer[0] != '\n' ) { void *temp; Name->CommentLines++; temp = realloc( Name->Comments, Name->CommentLines * sizeof * Name->Comments ); if ( temp != NULL ) { /* successful realloc - OK to assign (possibly new) pointer */ Name->Comments = temp; /* strdup is not a standard function */ Name->Comments[Name->CommentLines-1] = malloc( strlen(InputBuffer)+1); if ( Name->Comments[Name->CommentLines-1] != NULL ) { strcpy( Name->Comments[Name->CommentLines-1], InputBuffer ); } } else { /* oops, no more memory, can't store this comment */ Name->CommentLines--; } } /* now save Name somewhere before it gets lost */ printf( "Index=%d, X=%d, Y=%d, Dir=%c, NumComments=%d\n", Name->Index, Name->X, Name->Y, Name->Direction, Name->CommentLines ); } fclose(STRPfile); return 0; }
I compiled it withCode:Name='CF' Index=1, X=57, Y=40, Dir=W, NumComments=2 Name='CF in CA' Index=2, X=63, Y=12, Dir=W, NumComments=1 Name='WF Shield' Index=3, X=54, Y=7, Dir=W, NumComments=1 Name='Lee Cloud' Index=5, X=41, Y=1, Dir=W, NumComments=0 Name='Lee Cloud' Index=5, X=48, Y=11, Dir=E, NumComments=0 Name='Comma' Index=4, X=46, Y=8, Dir=E, NumComments=0
gcc -W -Wall -ansi -pedantic -O2 hello.c
If you're not compiling with a strong set of compiler options to diagnose all sorts of problems, I suggest you start.
@ Salem..
Thank you for taking a look at it. Your code was inspiring and helpes me to solve this problem and write the program.
@ Quzah
Maybe you were right and I was overcomplicating, but hey.. I am a newby in programming, and even more in C. So, i'll learn.. eventually.. Think that you will like my new code, it does (almost) what I want..
@ To all.. thanx for everyone looking at this code!!
Code:#include <string.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <unistd.h> #include <math.h> #define MAX_LINE (128+1) /* Maximum length of a source line plus one */ #define CM_NAME_LENGTH 20 #define MAX_INFO_LEN 2000 /* ************ Start of main ********************* */ int main() { char InputBuffer[MAX_LINE]; char StartJunk[5], NameString[CM_NAME_LENGTH]; int X1, X2, X3; int Y1, Y2, Y3; int idx, n, k, i, z; char C1, C2, C3, *INFO; FILE *STRPfile, *XML; idx = 0; n = 0; k = 0; i = 0; z = 0; /* ------------------------- XML STUFF --------------------------------*/ /* Write Satrep file in XML, plain stuff.. headers etc. need to be changed for file in which to write */ /* After that, you can write there with this: fprintf(AllInfosFile,"%s[%c,...]",variable); For example reasons I HAVE opened file astroXML.txt. Change is possible on later level */ XML=fopen("manu_xml.txt","w"); fprintf(XML,"<\?xml version=\"1.0\"\?>\n"); fprintf(XML,"<satrep source=\"ASII\" issuer=\"ZAMG\" valid-time=\""); /*fprintf(XML,Sr_date," YYYY,MM,DD");*/ fprintf(XML,"20041109"); /* THIS STILL HAS TO BE CHANGED!!!! */ fprintf(XML,"T"); /*fprintf(XML,Sr_date," hh,mm");*/ fprintf(XML,"1332"); /* THIS STILL HAS TO BE CHANGED!!!! */ fprintf(XML,"\" issue-time=\""); /*fprintf(XML,Sr_date," YYYY,MM,DD");*/ fprintf(XML,"20041109"); /* THIS STILL HAS TO BE CHANGED!!!! */ fprintf(XML,"T"); /*fprintf(XML,Sr_date," hh,mm");*/ fprintf(XML,"1332"); /* THIS STILL HAS TO BE CHANGED!!!! */ fprintf(XML,"\">\n"); /* above the header for xml file. Important that time and date are presented */ /* in the ISO-format. Next to that some info on by whom the SATREP was issued*/ /* The latter we can leave.. Its only for internal use by ZAMG, to outside world */ /* ------------------------- Open Satrep file --------------------------------*/ if ((STRPfile = fopen("SATREP.000", "r")) == NULL) { fprintf(stderr, "Error opening info-file :%s\n", "SATREP.000"); exit(1); } for (idx = 0; idx <= 21; idx++) { fgets(InputBuffer, MAX_LINE, STRPfile); } while (fgets(InputBuffer, MAX_LINE, STRPfile)) { sscanf(InputBuffer,"%4s %[^:]: %2d%2d%c (%2d%2d%c - %2d%2d%c)", StartJunk, NameString, &X1, &Y1, &C1, &X2, &Y2, &C2, &X3, &Y3, &C3); printf( "Name='%s'\n", NameString ); fprintf(XML,"<cm type=\""); fprintf(XML,"%s", NameString); fprintf(XML,"\" lon=\""); fprintf(XML,"%d",X1); fprintf(XML,"\" lat=\""); fprintf(XML,"%d",Y1); fprintf(XML,"\" preslon=\""); fprintf(XML,"%d",X1); fprintf(XML,"\" preslat=\""); fprintf(XML,"%d",Y1); fprintf(XML,"\">\n"); /* descriptions end with a blank line in the file */ INFO = (char *)malloc(MAX_INFO_LEN*sizeof(char)); sprintf(INFO,"\0"); while (!feof(STRPfile) && InputBuffer[0] != '\n') { fgets(InputBuffer, MAX_LINE, STRPfile); strcpy(INFO,InputBuffer); /*printf( "Info='%s'\n", INFO );*/ fprintf(XML,"%s",INFO); } fprintf(XML,"</cm>\n"); } fprintf(XML,"</satrep>\n"); /* End of file, last XML stament */ fclose(STRPfile); fclose(XML); return 0; }
You should change this. If your fgets fails here, you'll be trying to use data that doesn't exist. Remove the feof portion and replace it with the call to fgets, as both Salem and I have suggested on multiple occasions. (There's a reason we've both been saying to do it that way.)Code:while (!feof(STRPfile) && InputBuffer[0] != '\n') { fgets(InputBuffer, MAX_LINE, STRPfile); strcpy(INFO,InputBuffer); /*printf( "Info='%s'\n", INFO );*/ fprintf(XML,"%s",INFO); }
While you're at it, you may want to read FAQ entry on why using feof to control a loop is flawed.
Quzah.
Hope is the first step on the road to disappointment.
K.. Thnx for the tip. Might wanna pass that URL over to my boss.. His programs are full of it