Am I the only one who uses sscanf?

int level1 = 0, level2 = 0;
char levels[32], builder[32], area[32], *trimchr;
if (sscanf(credits, "@[EMAIL PROTECTED] [EMAIL PROTECTED]@[EMAIL PROTECTED]@x", 
levels, builder, area) < 3)
  log_string("Problem parsing credits string.");
if (sscanf(levels, "%d%d", &level1, &level2) < 2)
  log_string("Problem parsing levels from credits string.");
trimchr = &builder[strlen(builder)];
do {*(trimchr--) = '\0';}
while (*trimchr <= ' ');

So what are we doing?
sscanf uses an almost regular expression-style matching to parse variables out 
of a string.  Its return value is the number of arguments it matched.  So we 
sscanf once and see if we can match everything (4 variables).  If not, fall 
back on parsing without the levels.
Then I trimmed whitespace from the right of builder, since there was 
whitespace on the right of builder.

There are a couple of things that could make it better, but it would require 
more knowledge of the credits strings.
For example, is there ever a space in the builder's name?  If not, you could 
get away without doing the trim (match up to the first whitespace instead of 
the @ symbol).

--Palrich.

On Tuesday 23 December 2003 03:55 pm, Richard Lindsey wrote:
> Ok, I spent the last hour or so putting together a little function that
> *should* do it for you... none of it has been tested, so you'll have to
> do that, but if there are any bugs, they should be minor... also I don't
> promise that it's the most efficient way to do it memory-wise, but
> again, it should work :) just call it from whatever function you need
> the info parsed from, like if it's a find-area-for-this-mob's-level kind
> of command, you'd call it from there, and you'll have to declare the
> variables to use in that function... the parse function only parses to
> the variables you send it... so for example, if you were calling it from
> the parent function, you'd declare a variable for the lower level range,
> upper level range, creator name, and area name, like so:
>
> int minlvl, maxlvl;
> char creator[MAX_STRING_LENGTH], name[MAX_STRING_LENGTH];
>
> then when you loop through the area list or whatever you're searching
> through, call the function w/ those 4 variables, and the credits as the
> first argument to the function... assuming that you're using a variable
> called pArea as your AREA_DATA type, you'd call it like so from the
> parent function:
>
> parse_credits(pArea->credits,minlvl,maxlvl,creator,name);
>
> and then for this credit line: "@w{ 1 [EMAIL PROTECTED] Diku      @[EMAIL 
> PROTECTED]"
> it should set the following values (it'll strip the color codes too):
>
> minlvl = 1;
> maxlvl = 99;
> creator = "Diku";
> name = "REverdale";
>
> which you can then use from the parent function... hope it helps...
>
> void parse_credits( char *credits, minlvl, maxlvl, creator, name )
> {
>     char *point, *point2, *levels, buf[MAX_STRING_LENGTH];
>     char buf2[MAX_STRING_LENGTH], value[MAX_STRING_LENGTH];
>
>     buf[0] = '\0';
>     point2 = buf;
>
>     /* First strip the color codes */
>     for ( point = credits; *point; ++point )
>     {
>         if ( *point == '@' )
>         {
>             ++point;
>             continue;
>         }
>
>         *point2 = *point;
>         *++point2 = '\0';
>     }
>
>     /* Now point2 should be a black and white version of credits,
>        so we just break it up into arguments, which means 1 more
>        loop to isolate level range before we use one_argument */
>     point2 = buf;
>     buf2[0] = '\0';
>     levels = buf2;
>     for ( point = point2; *point; ++point )
>     {
>         if ( *point == '{' )
>             continue;
>         else if ( *point == '}' )
>         {
>             ++point;
>             break;
>         }
>
>         *levels = *point;
>         *++levels = '\0';
>     }
>
>     /* Now levels should contain just the segment within the
>        braces, and point should contain everything after the
>        braces, and we can use one_argument for the rest... */
>     levels = one_argument(levels,value);
>
>     if ( !is_number(value) )
>         log_string("Invalid numeric argument in area credits (minlvl)");
>     else minlvl = atoi(value);
>
>     levels = one_argument(levels,value);
>
>     if ( !is_number(value) )
>         log_string("Invalid numeric argument in area credits (maxlvl)");
>     else maxlvl = atoi(value);
>
>     point = one_argument(point,creator);
>     point = one_argument(point,name);
>     return;
> }
>
> Richard Lindsey
>
> -----Original Message-----
> From: Mervine, Keith [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, December 23, 2003 2:27 PM
> To: [email protected]
> Subject: Taking a string and separating it into different vars
>
> Hello all.
>
> I need to take my Credits line of my area files and separate it into
> 3 separate variables...and example of my credits line is as follows.
>
> The credits are  char *credits
>
> @w{ 1 [EMAIL PROTECTED] Diku      @[EMAIL PROTECTED]
> @[EMAIL PROTECTED] Thalor    @RThe Tower of [EMAIL PROTECTED]
> @w{ 5 [EMAIL PROTECTED] Strahd    @RTown Of [EMAIL PROTECTED]
>
> the @'s are my color code...
>
> What I need is to have the vars like this
>
> levels = 1-99
> creator = Diku
>
> Can someone give me a hint on how to start?
>
>
> Thanks!
>
> -K
>
> --
> ROM mailing list
> [email protected]
> http://www.rom.org/cgi-bin/mailman/listinfo/rom


Reply via email to