Phantasmal MUD Lib for DGD

Phantasmal Site > DGD > DGD LPC Reference > Character Manipulation

Manipulating Character Strings


Date: Fri, 30 Mar 2001 01:57:32 +0200
From: Erwin Harte
Subject: Re: [DGD]Adding character to string

On Fri, Mar 30, 2001 at 01:30:43AM +0200, Frantisek Fuka wrote:
> I have this problem with DGD 1.2. The solution is probably very simple 
> but I couldn't come up with anything elegant and it drives me mad.
> 
> I need to be able to get the character according to its ASCII number. 
> For example, if I have string str = "foo" and integer num = 65, i need 
> to somehow do (str + (char)num) and get "fooA", but I keep getting 
> "foo65" and I can find no function to convert 65 to "A". I know it can 
> be done by doing
> str = "foo?"; str [3] = num; /* replaces '?' with 'A' */

Right, so what about:

    string
    chr(int c)
    {
	string s;

	s = " ";
	s[0] = c;
	return s;
    }

I agree, a bit of overhead, but once you've got that, it's very
elegant to be doing

    str += chr(65);

and have it work as intended.

> but that seems cumbersome to me. Specifically, I need to use the 
> following function for translating all output from one character coding 
> to other so it has to be quick and elegant (it also adds '\x0D' before 
> each "\n" because i use binary port for output):
> 
> string out;
> out = "";
> for (i=0; i<strlen(msg); i++) {
> if (msg[i] == '\n') out += '\x0D';
> out += (msg[i] >= 128) ? charset_output[msg[i]-128] : msg[i];
> }
> 
> Unfortunately, instead of character (for example 'A'), the string "65" 
> is being added to 'out' variable.

The reason for this is that the 'x' constants are really int values,
so what the compiler thinks you're doing is:

    <string> = <string> + <int>;

Which means you get:

    <string> = <string> + (string)<int>

So the compiler is doing what you're telling it to, not what you want
it to. ;-)

I'd do it this way:

    int    i, len;
    string out;

    out = implode(explode("\n" + msg + "\n", "\n"), "\r\n");
    for (i = 0, len = strlen(out); i < len; i++) {
        out[i] &= 0x7f;
    }

Hope that helps,

Erwin.
-- 
Erwin Harte      : `Don't mind Erwin, he gets crabby. :)'

Date: Fri, 30 Mar 2001 02:59:04 +0200
From: Erwin Harte
Subject: Re: [DGD]Adding character to string

On Fri, Mar 30, 2001 at 01:57:32AM +0200, Erwin Harte wrote:
> On Fri, Mar 30, 2001 at 01:30:43AM +0200, Frantisek Fuka wrote:
[...]
> 
> I'd do it this way:
> 
>     int    i, len;
>     string out;
> 
>     out = implode(explode("\n" + msg + "\n", "\n"), "\r\n");
>     for (i = 0, len = strlen(out); i < len; i++) {
>         out[i] &= 0x7f;
>     }

Silly me, there I went and ignored the charset_output(..) function
you're using.  Replace the 'out[i] &= 0x7f' with:

          if (out[i] & 0x80) {
              out[i] = charset_output(out[i] - 0x80);
          }

An alternative approach (which, I should say, was suggested by Dworkin
and not one I came up with) would be to use parse_string() with a
grammar like this:

    lo = /[\x00-\x7f]+/
    hi = /[\x00-\x7f]+/

    text = chunks chunk
    text = chunk

    chunk = lo
    chunk = hi ? convert_output

Where convert_output would be a function like this:

    string
    convert_output(mixed *tree)
    {
        int i, len;
        string str;

        str = tree[0];
        for (i = 0, len = strlen(str); i < len; i++) {
            str[i] = charset_output(str[i] - 0x80);
        }
        return ({ str });
    }

The two functions required for the text grammar-rules are left as an
exercise to the reader. ;-)

Erwin.
-- 
Erwin Harte      : `Don't mind Erwin, he gets crabby. :)'

From: dgd at list.imaginary.com (Kris Van Hees)
Date: Wed Nov 26 15:40:04 2003
Subject: [DGD] string indexing..

I believe this is intentional behaviour, to be sonsistent in how string ranges
can work.  The str[i .. i + 1] construct returns a string that is 2 characters
long (assuming strlen(str) > i  + 1 of course), str[i .. i] returns a string
that is 1 character long, and this str[i .. i - 1] returns a string that is 0
characters long.  It does make sense if you look at it that way.

	Kris

On Wed, Nov 26, 2003 at 10:36:05PM +0000, Bart van Leeuwen wrote:
> Hmm.. it seems to me that doing something like "blah"[0..-1] should result
> in an invalid string range error, but it does not, it results in an empty
> string (checked on dgd 1.1, 1.2p3).
> 
> Looking through str.c in various versions points at str_ckrange and
> str_range.
> The particular issue is checking on l1 > l2 + 1, which should either be
> l1 > l2 or l1 >= l2 + 1 (why would you write it like that anyway?)
> 
> Was wondering for a sec if it was a feature, but theres cleaner ways to
> get an empty string I figured so I guess it is a bug :)
> 
> Btw, I ended up there because I wanted to get indexing from the end of a
> string working (ie, str[0..-3] is short for str[0..strlen(str)-3] (oh, and
> a bit faster also of course), and besides, I like the driver just
> returning an empty string instead of throwing a runtime error when trying
> to index past the end of the string ;) (and I ended up there due to
> wanting a much closer emulation of lpmud, but more about that later maybe)
> 
> Anyway, if people are interested I will cleanup the code for it a bit and
> make a patch available. It seems to work with all I threw at it, but
> wasn't tested very extensively yet.
> 
> Bart.