// saved from url // http://www-cs.canisius.edu/PL_TUTORIALS/C++/EXAMPLES/MRD/SRC/parseline.c --> //---------------------------------- parseline.c ------------------------- #include <stdlib.h> #include <string.h> #include "parseline.h" parseline::parseline (char *line) { numwords = 0; parse (line); } parseline::parseline () { numwords = 0; } void parseline::set (char *line) { freeup (); numwords = 0; parse (line); } parseline::~parseline() { freeup(); } void parseline::freeup () { int i; for (i=0; i<numwords; i++) { delete [] (words[i]); words[i] = 0; } } int parseline::parse (char *line) { int i; char newword[MAXWORDLENGTH+1]; char *string = line; numwords = 0; while (1) { /* Check to see if there is room for another word in our array. If not, then we just as well quit and not waste our time looking for the next word. */ if (numwords == MAXWORDS) return 1; /* Skip over leading blanks */ while (string && *string == ' ') string++; if (*string == 0) return 0; /* At this point, we know we are sitting on the first character of our next word and are not at the end of the string. So we collect the characters into newword until we find a blank or a NULL. If the first character is a double quote mark, then this is not really part of our word, and we do not stop at blanks, but continue on until we see the next double quote. Right now we can't handle embedded quote marks. */ i = 0; if (*string == '\"') { string++; while (i < MAXWORDLENGTH) { if (*string == 0 || *string == '\"') break; newword[i] = *string; string++; i++; } if (*string == '\"') string++; } else { while (i < MAXWORDLENGTH) { if (*string == 0 || *string == ' ') break; newword[i] = *string; string++; i++; } } newword[i] = 0; /* ensure an ASCII null at end of newword. */ /* install into array */ words[numwords] = new char [strlen(newword)+5]; strcpy (words[numwords], newword); numwords++; /* If we were stopped by an ASCII NULL above, we exit the loop and immediately return to the calling routine. */ if (*string == 0) break; /* Else we were stopped by the terminator character. Skip over it. */ if (*string == ' ') string++; } return 0; } void parseline::setword (int fieldnum, char *newvalue) { delete words[fieldnum]; words[fieldnum] = new char[strlen(newvalue)+5]; strcpy (words[fieldnum], newvalue); } // The following is used when you need to write out the fields // with blanks in between. // The width of the field is determined by getting the field's width from // the character string widths. This consists of a number of integers, // separated by blanks. If the first character is a dollar sign, then // there is just one width, which follows the number sign. // The resulting line goes into "result." void parseline::makeline (char *result, char *widths) { int use_default = 0, width; int wi=0; // width index if (widths[0] == '$') { use_default = 1; width = atoi(&widths[1]); } strcpy (result, ""); for (int i=0; i<numwords; i++) { char temp[1000]; int embedded_blanks = 0; strcpy (temp, words[i]); for (int j=0; j<strlen(temp); j++) if (temp[j] == ' ') { embedded_blanks = 1; break; } if (embedded_blanks) strcat (result, "\""); strcat (result, words[i]); if (embedded_blanks) strcat (result, "\""); int used = strlen(temp); if (embedded_blanks) used += 2; if (i == numwords-1) continue; // don't pad at end with blanks // get next number from widths char num[100]; int k = 0; if (!use_default) { while (1) { char ch = widths[wi]; if (ch == 0) break; wi++; if (ch == ' ') break; num[k++] = ch; } num[k] = 0; width = atoi (num); } int leftover = width - used; if (leftover <= 0) leftover = 1; while (leftover) { leftover--; strcat (result, " "); } } } // The following is used to make up a line with just one blank in between. void parseline::makeline (char *result) { makeline (result, "$1"); } 1