Nigel Grant wrote:
I am having trouble deciding how to extract two strings from one string.

My string contains a phone number & a name eg. "me | +61 (0) 408 409 409"

I want to have two string variables that contain "me" & "+61 (0) 408 409 409"

Should I use StrChr or StrStr ?

Since you need to break on a string that is longer than a single character, it makes sense to use StrStr().

I have tried to write my own, I'm having trouble as these are pointers
not values.

Pointers can be tricky. It just takes practice. (By the way, pointers *are* values...)

If you'd like, strings in C can be treated as arrays of characters,
and you can just use array notation instead.  For example:

        Char *mystr = (Char *) MemPtrNew (5);

        mystr[0] = 'P';
        mystr[1] = 'a';
        mystr[2] = 'l';
        mystr[3] = 'm';
        mystr[4] = 0;

That code will set mystr to "Palm" (at least assuming MemPtrNew()
doesn't return NULL).

You can even take it so far as to convert the pointer that StrStr()
returns into an index into the array:

        const Char *needle = "Paul";
        const Char *haystack = "John Paul George Ringo";
        const Char *foundptr;
        
        Int32 paulindex;

        foundptr = StrStr (haystack, needle);
        if (foundptr == NULL)
        {
            paulindex = -1;     // we'll let -1 indicate "not found"
        }
        else
        {
            paulindex = foundptr - haystack;
        }

After this code is run, paulindex should have the value 5.
That's because foundptr will point at "P", which is 5 slots
further into the string than the beginning, which is what
haystack points to.

Well anyway, that was a giant sidetrack.

The point is, there are going to be three important positions
within that original string.  There's (a) the start of the
string, and (b) the start of the delimiter (" | " in your case),
and (c) the start of the stuff after the delimiter.

So, what do we know about those positions?  Well, we know
that the start of the stuff after the delimiter equals the
start of the delimiter itself plus the length of the delimiter.

And we also know that StrStr() will give us the start position
of the delimiter.

And, we *also* know the length of the first string is equal
to its start position subtracted from the position of the
thing that immediately follows it (the delimiter).  We know
this through sort of the inverse of the reasoning that appears
two paragraphs back.

So, let's say we want to just find the start positions of
everything and not worry about splitting.  That's not so
hard given what we already established that we know:

        void FindPositions (Char *origstr)
        {
            const Char *delimiter = " | ";
            Int32 delimiterlen = StrLen (delimiter);

            Char *firststart;
            Char *delimiterstart;
            Char *secondstart;

            // the first string starts at the beginning
            firststart = origstr;

            // StrStr() will just tell us where the delimiter starts
            delimiterstart = StrStr (origstr, delimiter);
            if (delimiterstart == NULL) { return; }

            // the second strings starts right after the delimiter
            secondstart = delimiterstart + StrLen (delimiter);
        }

OK, that wasn't too hard.  But still, how do you split them?
Well, one way to do it is to modify origstr.  (This assumes
origstr is writable memory!)  You can just replace the first
character of the delimiter with a 0; that will cause everything
before it to be valid C string, because C strings are just
neverending sequences of characters except that they end if
one of the characters is a zero.  You might worry about
overwriting something important, but since the 0 character is
just one byte, and since the delimiter has to be AT LEAST one
byte (how could it be shorter?) that's OK, as long as you
are OK with clobbering the delimiter.

But what about the second string?  Well, it already has a NULL
terminator at the end of it, so it's *already* a valid string.
So all you need to do is make sure you have a pointer to the
beginning of it, and you can use it as a string.

So, you can find the first string and advance to the second
with a function like this (note that it's virtually identical
to the above function, except I've added a few lines.

        Char *BreakUpString (Char *origstr)
        {
            const Char *delimiter = " | ";
            Int32 delimiterlen = StrLen (delimiter);

            Char *firststart;
            Char *delimiterstart;
            Char *secondstart;

            // the first string starts at the beginning
            firststart = origstr;

            // StrStr() will just tell us where the delimiter starts
            delimiterstart = StrStr (origstr, delimiter);
            if (delimiterstart == NULL)
            {
                // we have to return something to signal an error
                return NULL;
            }

            // the second strings starts right after the delimiter
            secondstart = delimiterstart + StrLen (delimiter);

            // add a null terminator after first string
            *delimiterstart = 0;

            // return the start of the second string
            return (secondstart);
        }

You could use this code thusly:

        Char buf[SOMELENGTH];
        StrCopy (buf, "me | +61 (0)...");

        Char *name;
        Char *number;

        number = BreakUpString (buf);
        name = buf;

Hope that helps.

  - Logan

--
For information on using the Palm Developer Forums, or to unsubscribe, please 
see http://www.palmos.com/dev/support/forums/

Reply via email to