Another suggestion... str_cew (STRing Cap Every Word)

Login to reply  Page: « < 1 of 1 > »
13 Jul 2010 - 04:592841
Another suggestion... str_cew (STRing Cap Every Word)
A recent discussion elsewhere lead to me writing this function essentially for someone else. But then I decided it would be a good addition to my own MUD, and after thinking that, I also thought possibly to tbaMUD's core as well.

First, me on my MUD using it with my imm via my testing command (which is usually just send_to_char(ch, "Does Nothing!\r\n"); unless I've placed test code in it like right now)
Quote:
50000Hp 50000Ma 50000Mv> immtest boogie woogie
str_cew output: Boogie Woogie


Now for the do_immtest code so you can see how its used
ACMD(do_immtest)
{
	char buf[MAX_STRING_LENGTH];
	str_cew(argument, buf);
	send_to_char(ch, "str_cew output: %s\r\n", buf);
}

The prototype for str_cew in utils.h
I'm considering changing this from void to int and having it return either the number of words capped, OR the total length in bytes... any input on this?
void str_cew(char *argument, char *new_arg);
The function in utils.c, as I said above for the prototype, considering changing this to int and doing some type of return value.
/*
 * str_cew: Function to capitalize the first letter each word in a string.
 * All other letters in the string are returned returned in lower case.
 *
 * Does not modify original string. Returns void.
 */
void str_cew(char *argument, char *new_arg)
{
  if (!argument || !*argument) {
    log("SYSERR: str_cew received a NULL pointer!");
	*new_arg = '{{uie-code}}';
    return;
  }
  
  if (argument == '{{uie-code}}') {
    log("SYSERR: str_cew received no argument!");
	*new_arg = '{{uie-code}}';
    return;
  }

  /* CircleMUD function to strip leading spaces from the string */
  skip_spaces(&argument);

  *(new_arg++) = UPPER(*argument);
  argument++;
  while (*argument) {
	if (isspace(*argument)) {
	  *(new_arg++) = *argument;
      argument++;
	  if (*argument != '{{uie-code}}')
	    *(new_arg++) = UPPER(*argument);
	} else {
	  *(new_arg++) = LOWER(*argument);
	}
	if (*argument != '{{uie-code}}')
      argument++;
  }
  
  *new_arg = '{{uie-code}}';

  return;
}


__________________
Owner/Coder/Head Admin
Caer Dubrin

Last edited by ralgith (13 Jul 2010 - 08:38) Reason: Removed unnecessary LOWER(), thanks Jamdog
13 Jul 2010 - 08:342842
Nice function! I can see a few applications for this.

One minor thing I can see in the code though:
if (isspace(*argument)) {
	  *(new_arg++) = LOWER(*argument);
      argument++;
Surely, there is no need to LOWER whitespace? Can't this just be:
if (isspace(*argument)) {
	  *(new_arg++) = *argument;
      argument++;


__________________

Last edited by Jamdog (13 Jul 2010 - 08:53)
13 Jul 2010 - 08:362843
DOH! Thanks Jamdog, yes it can be.

I know I repeat this a lot, but its so nice to have someone else able to read and check your code. It doesn't hurt to LOWER a whitespace, but why waste the extra processing doing so?


__________________
Owner/Coder/Head Admin
Caer Dubrin
13 Jul 2010 - 09:012844
Another thing I just spotted ;)

if (argument == '{{uie-code}}') {
    log("SYSERR: str_cew received no argument!");
	*new_arg = '{{uie-code}}';
    return;
  }
Not sure what '{{uie-code}}' is, as the code box messed up the code, but, assuming it's either '\0' or '\x0'
1) shouldn't argument be *argument. argument is a char* pointer and you seem to be comparing it to a char value...?
2) You already checked above for *argument being NULL (an empty string), do you need to check it again?


__________________

Last edited by Jamdog (13 Jul 2010 - 09:02)
13 Jul 2010 - 10:242845
After adding this to a MUD for testing, I noticed your code also doesn't handle multiple spaces between words, so added a fix for that, and tweaked a few other bits - below is the function as I now have it, and I've tested it as thoroughly as I can think of
> test this is a  test   of the  cew    function
Output  : This Is A  Test   Of The  Cew    Function
> test This 1s a test with numerical words 123 3e e3 3ee ee3
Output  : This 1s A Test With Numerical Words 123 3e E3 3ee Ee3
> test Another with symbols +10 1+1=2     $ten &fish f^sh
Output  : Another With Symbols +10 1+1=2    $ $$ten &fish F^sh
> test EEEEEK, IT'S A DRAGON!
Output  : Eeeeek, It's A Dragon!
Here's the function with my edits, as you will see, I've also tweaked the NULL pointer checks at the start:
/*
 * str_cew: Function to capitalize the first letter each word in a string.
 * All other letters in the string are returned returned in lower case.
 *
 * Does not modify original string. Returns void.
 */
void str_cew(char *argument, char *new_arg)
{
  *new_arg = '\x0';

  if (!argument || !new_arg) {
    log("SYSERR: str_cew received a NULL pointer!");
    return;
  }

  if (!*argument) {
    log("SYSERR: str_cew received no argument!");
    return;
  }

  /* CircleMUD function to strip leading spaces from the string */
  skip_spaces(&argument);

  *(new_arg++) = UPPER(*argument);
  argument++;

  while (*argument) {
    if (isspace(*argument)) {
      while (*argument && isspace(*argument)) {
        *(new_arg++) = *argument;
        argument++;
      }
      if (*argument != '\x0') {
        *(new_arg++) = UPPER(*argument);
      }
    } else {
      *(new_arg++) = LOWER(*argument);
    }
    if (*argument != '\x0')
      argument++;
  }

  *new_arg = '\x0';

  return;
}


__________________

Last edited by Jamdog (13 Jul 2010 - 10:29)
13 Jul 2010 - 15:142846
The extra check for argument being '\0' you're perfectly right about being unnecessary as well, and nice point with the multiple spaces. I appreciate the ideas/fixes. That's what happens when you're writing code while having an insomniatic episode.


__________________
Owner/Coder/Head Admin
Caer Dubrin
13 Jul 2010 - 15:412847
Here's what it looks like now, with credits:
/*
 * str_cew: Function to capitalize the first letter each word in a string.
 * All other letters in the string are returned returned in lower case.
 * Does not modify original string. Returns void.
 *
 * Written by Ulath of Caer Dubrin 12 July 2010
 * Feature and Bugfix suggestions Jamdog of tbaMUD forums 13 July 2010
 */
void str_cew(char *argument, char *new_arg)
{
  *new_arg = '\x0';

  if (!argument || !new_arg) {
    log("SYSERR: str_cew received a NULL pointer!");
    return;
  }

  if (!*argument) {
    log("SYSERR: str_cew received no argument!");
    return;
  }

  /* CircleMUD function to strip leading spaces from the string */
  skip_spaces(&argument);

  *(new_arg++) = UPPER(*argument);
  argument++;

  while (*argument) {
    if (isspace(*argument)) {
      while (*argument && isspace(*argument)) { /* Loop here, so we can work with multiple spaces. Thanks Jamdog */
        *(new_arg++) = *argument; /* Since this is a space, we don't need to use LOWER on it. Thanks Jamdog. */
        argument++;
      }
      if (*argument != '\x0') {
        *(new_arg++) = UPPER(*argument);
      }
    } else {
      *(new_arg++) = LOWER(*argument);
    }
    if (*argument != '\x0')
      argument++;
  }

  *new_arg = '\x0';

  return;
}

I'm doing to be doing a str_cww() function (CAP Whole Word) next, which will be interesting to work on.
I'm not sure how I plan on doing it just yet, we'll see when the time comes. For now I'm out for a few hours.


__________________
Owner/Coder/Head Admin
Caer Dubrin
14 Jul 2010 - 16:512848
str_cww
Here's str_cww.

I've created a separate .c and .h file for these functions I've called my_str.c/h
Once I write the num_words() function I put in the comments I'll post the file for everyone to download.

/*
 * str_cww: Function to capitalize a whole word in a string.
 * If lower == TRUE all other letters in the string are returned returned in lower case, otherwise they're left as is.
 * Does not modify original string. Returns void.
 *
 * Written by Ulath of Caer Dubrin 14 July 2010
 */
void str_cww(char *argument, char *new_arg, int pos, bool lower)
{
	int loc = 1;

	*new_arg = '\x0';
 
	if (!argument || !new_arg) {
		log("SYSERR: str_cww received a NULL pointer!");
		return;
	}
 
	if (!*argument) {
		log("SYSERR: str_cww received no argument!");
		return;
	}
	
	if (pos < 1) { /* Need to write a num_words() function so I can add || pos > num_words to this */
		log("SYSERR: ctr_cww did not receive a valid word number!");
		return;
	}
 
	/* CircleMUD function to strip leading spaces from the string */
	skip_spaces(&argument);
 
	while (*argument && loc != pos) {
		if (isspace(*argument)) {
			while (*argument && isspace(*argument)) {
				*(new_arg++) = *argument;
				argument++;
			}
			loc += 1;
		} else {
			if (lower == TRUE)
				*(new_arg++) = LOWER(*argument);
			else
				*(new_arg++) = *argument;
			argument++;
		}
	}
	
	if (loc != pos) { /* This is needed until I add the num_words as described above */
		log("SYSERR: End of string reached, but desired word position not reached!");
		new_arg = '\x0';
		return;
	}
	
	/* loc = pos, so now we upper the whole word */
	while (*argument && !isspace(*argument)) {
		*(new_arg++) = UPPER(*argument);
		argument++;
	}
	
	/* If we haven't finished our string yet, fill the rest of it into new_arg */
	if (*argument != '\x0') {
		while (*argument) {
			*(new_arg++) = LOWER(*argument);
			argument++;
		}
	}
 
	*new_arg = '\x0';
 
	return;
}


__________________
Owner/Coder/Head Admin
Caer Dubrin
15 Jul 2010 - 14:222867
Available for download now @ MudBytes:
http://www.mudbytes.net/file-2760


__________________
Owner/Coder/Head Admin
Caer Dubrin
15 Jul 2010 - 17:062872
hoorah!


15 Jul 2010 - 17:202874
Quote rudeboyrave:
hoorah!


I take it you like it? ;)
I'm about to upload it to Jamdog's site with a minor update too.


__________________
Owner/Coder/Head Admin
Caer Dubrin
15 Jul 2010 - 17:582877
Quote ralgith:

I'm about to upload it to Jamdog's site with a minor update too.

Link to it is here. ;)


__________________
15 Jul 2010 - 18:132879
Thanks Jam :D


__________________
Owner/Coder/Head Admin
Caer Dubrin
Login to reply  Page: « < 1 of 1 > »