Board index » cppbuilder » string, String and AnsiString - lost in a sea of confusion

string, String and AnsiString - lost in a sea of confusion


2005-03-02 01:04:00 AM
cppbuilder11
Well this is a pretty pickle and no mistake :o(
Trying to implement the function from my previous posting I realised
that there's very subtle differneces between these two (assuming I'm
correct and String is identical to AnsiString). Problem started with
String.Length() which I was using to detect when I was at the end of a
String. Looks, though, like this is actually a pointer to the address
at the very end of teh memory reserved for the string (or such) and
thus Doesn't Work (woe is me).
Not being able to find how you detect the end of the (Ansi)String I
tried using std::string which seems to be documented as basic_string.
Was getting soemwhere here BUT, I'm reading from and writing to a rich
text control and BCB sees only to want to deal with Strings, claiming
it can't convert between the two types - i.e. I can't write my
resulting text to my form.
Be greatful for general responses here on what to stick to and why.
More specifically; how do I get the length of a String - the line
that's giving me the problem is:
while (Position<=thisText.Length());
Position is a counter that steps through the text a character at a
time from the start.
Marshal
BTW - the de-{*word*81} refers to line numbers - is there a way of getting
line numbers to appear in the editor?
 
 

Re:string, String and AnsiString - lost in a sea of confusion

"Marshal Anderson [Novice]" < XXXX@XXXXX.COM >
wrote in message news: XXXX@XXXXX.COM ...
Quote
Well this is a pretty pickle and no mistake :o(

Trying to implement the function from my previous posting I realised
that there's very subtle differneces between these two (assuming I'm
correct and String is identical to AnsiString). Problem started with
String.Length() which I was using to detect when I was at the end of a
String. Looks, though, like this is actually a pointer to the address
at the very end of teh memory reserved for the string (or such) and
thus Doesn't Work (woe is me).
Not sure what your exact problem is but Length() should return
the length in chars of the AnsiString. I'm not sure what you
mean by returning a pointer to the address at the end.
What may be confusing you
is that AnsiString is 1 based and not 0 based like std::string or
char arrays. So if you're parsing it with a for loop for example
you want to do:
for(int i = 1, len = SomeString.Length(); i <= len; ++i)
Notice that you start at 1 and go to <= length.
HTH
 

Re:string, String and AnsiString - lost in a sea of confusion

On Tue, 01 Mar 2005 17:04:00 GMT, Marshal Anderson [Novice] wrote:
Quote
Not being able to find how you detect the end of the (Ansi)String I
tried using std::string which seems to be documented as basic_string.
Was getting soemwhere here BUT, I'm reading from and writing to a rich
text control and BCB sees only to want to deal with Strings, claiming
it can't convert between the two types - i.e. I can't write my
resulting text to my form.
String is indeed AnsiString, luckily both AnsiString and std::string
have c_str() methods viz:
AnsiString AS1 = "A string";
std::string ss1 = AS1.c_str();
std::string ss2 = "another";
AnsiString AS2 = ss2.c_str();
Please note, AnsiString is 1 based (like Delphi String, which it
mimics) std::string is 0 based.
int X = AS1.Length();
AS1 = AS1.SubString(1,3);
int Y = AS2.Length();
--
Good luck,
liz
 

{smallsort}

Re:string, String and AnsiString - lost in a sea of confusion

"Marshal Anderson [Novice]" < XXXX@XXXXX.COM >
wrote in message news: XXXX@XXXXX.COM ...
Quote
assuming I'm correct and String is identical to AnsiString
You are correct. String (capital 'S') is just a typedef for AnsiString.
Quote
Problem started with String.Length() which I was using to detect
when I was at the end of a String. Looks, though, like this is
actually a pointer to the address at the very end of teh memory
reserved for the string (or such) and thus Doesn't Work (woe is me).
Why doesn't that work for you? The Length() *is* at the end of the string.
Quote
I'm reading from and writing to a rich text control and BCB sees
only to want to deal with Strings, claiming it can't convert between
the two types - i.e. I can't write my resulting text to my form.
The VCL has no concept of std::string at all. To convert a std::string to
an AnsiString, and vice versa, you need to use the _str() method of each
class to pass char* pointers around, ie:
AnsiString s1 = "whatever";
std::string s2 = s1.c_str();
s1 = s2.c_str();
Quote
More specifically; how do I get the length of a String
You already know the answer to that - AnsiString::Length() and
std::string::length().
Quote
the line that's giving me the problem is:

while (Position<=thisText.Length());
Please show more code. That snippet does not show the context in which it
is being used.
Gambit
 

Re:string, String and AnsiString - lost in a sea of confusion

On Tue, 1 Mar 2005 11:07:27 -0800, "Remy Lebeau \(TeamB\)"
< XXXX@XXXXX.COM >wrote:
Quote
>the line that's giving me the problem is:
>
>while (Position<=thisText.Length());

Please show more code. That snippet does not show the context in which it
is being used.

OK - this isn't complete as it doesn't yet push the words into the
vector.
StringVector splitText(String thisText)
{
int unsigned Position=0;
String oneWord="";
StringVector vecBox (10); // create empty vector
do
{
oneWord="";
do
{
oneWord=oneWord+thisText.SubString(Position,1);
Position++;
}
while (thisText.SubString(Position,1) !=" ");
CutUps->ShowCutText->Text=oneWord;
}
while (Position<=thisText.Length());
return vecBox;
}
Using break-points I can see it works in priinciple, but the final
while goes way beyond the the end of the string - Length() generates,
for instance, the following:00402F54 when the string is just a couple
of hundred chars long.
Re the points above about detecting word splits with other characters
that space etc. - this app only needs some basic way to split the
content - it will (eventually) take two texts and randomly combine
them - acuracy isn't that inportant (luckily).
Marshal
 

Re:string, String and AnsiString - lost in a sea of confusion

"Marshal Anderson [Novice]" < XXXX@XXXXX.COM >
wrote in message news: XXXX@XXXXX.COM ...
Quote
int unsigned Position=0;
AnsiString is 1-indexed, not 0-indexed.
Quote
do
{
oneWord=oneWord+thisText.SubString(Position,1);
Position++;
}
while (thisText.SubString(Position,1) !=" ");
You are calling SubString() to retrieve a single character. You can use the
'[]' operator instead:
do
{
oneWord += thisText[Position++];
}
while( thisText[Position] != ' ');
With that said, a more efficient approach is to use AnsiStrChar() instead of
a do..while loop:
StringVector splitText(String thisText)
{
char *ptr = thisText.c_str();
char *end = ptr + thisText.Length();
StringVector vecBox;
// skip preceeding whitespace...
while( (ptr < end) && (*ptr <= ' ') ) ++ptr;
// while there is still data available...
while( ptr < end )
{
char *ptr2 = ptr+1;
// find the end of the current word
while( (ptr2 < end) && (*ptr2>' ') ) ++ptr2;
// save the current word
vecBox.push_back(String(ptr, ptr2-ptr));
// skip trailing whitespace...
while( (ptr2 < end) && (*ptr2 <= ' ') ) ++ptr2;
ptr = ptr2;
}
return vecBox;
}
Or, if you use std::string instead of String, you can use the code I gave
you in another discussion earlier.
Gambit
 

Re:string, String and AnsiString - lost in a sea of confusion

On Wed, 2 Mar 2005 02:44:16 -0800, "Remy Lebeau \(TeamB\)"
< XXXX@XXXXX.COM >wrote:
Quote

"Marshal Anderson [Novice]" < XXXX@XXXXX.COM >
wrote in message news: XXXX@XXXXX.COM ...

>int unsigned Position=0;

AnsiString is 1-indexed, not 0-indexed.
OK - didn;t cause problems, but the 'some start at 0, some at 1'
problem is familier from VB6 :o)
Quote

>do
>{
>oneWord=oneWord+thisText.SubString(Position,1);
>Position++;
>}
>while (thisText.SubString(Position,1) !=" ");

You are calling SubString() to retrieve a single character. You can use the
'[]' operator instead:

do
{
oneWord += thisText[Position++];
}
while( thisText[Position] != ' ');
That's helpful - I'm slowly learning how to find the shortest method
for things. I actually understand these examples :o)
Quote
With that said, a more efficient approach is to use AnsiStrChar() instead of
a do..while loop:

StringVector splitText(String thisText)
{
char *ptr = thisText.c_str();
OK - so you create a character array from thisText and *ptr points to
the start of it.
Quote
char *end = ptr + thisText.Length();
Ok - this looks useful - But your use of Length is exactly the same
as mine - I still don't know why I was getting that huge number
instead of the length of the string. *end is a pointer to the end of
the string yes?
You don't declare *end or *ptr - is that simply not needed, or a
useful short-cut? Or do char *end/*ptr have some specific meaning in
C++
Quote
StringVector vecBox;

// skip preceeding whitespace...
while( (ptr < end) && (*ptr <= ' ') ) ++ptr;
Not sure of the difference between ptr and *ptr and end and *end - one
is a value and the other a pointer, but don't see the functional
difference.
Quote
// while there is still data available...
while( ptr < end )
{
char *ptr2 = ptr+1;

// find the end of the current word
while( (ptr2 < end) && (*ptr2>' ') ) ++ptr2;

// save the current word
vecBox.push_back(String(ptr, ptr2-ptr));

// skip trailing whitespace...
while( (ptr2 < end) && (*ptr2 <= ' ') ) ++ptr2;
ptr = ptr2;
}

return vecBox;
}


Or, if you use std::string instead of String, you can use the code I gave
you in another discussion earlier.
Presumably I could use c_str() to create a function to convert between
string and String - you think????
Thanks for your patience. What I'm trying not to do is drop whole
solutions into my code, but to understand why I'm wrong - that way I
should eventually lose my training wheels :o)
Marshal
 

Re:string, String and AnsiString - lost in a sea of confusion

"Marshal Anderson [Novice]" < XXXX@XXXXX.COM >
wrote in message news: XXXX@XXXXX.COM ...
Quote
>char *ptr = thisText.c_str();
OK - so you create a character array from thisText and *ptr points to
the start of it.
No, I am not creating any array at all. The String already contains an
array of characters. I am simply declaring a pointer that point to the
start of that existing memory.
Quote
>char *end = ptr + thisText.Length();

Ok - this looks useful - But your use of Length is exactly
the same as mine - I still don't know why I was getting that
huge number instead of the length of the string.
It is not possible for Length() to return an invalid value, unless the
String itself has been corrupted beforehand. The length of the string is
stored in a structure preceeding the characters themselves. If the String
is pointing to the correct memory for the actual characters, then it is also
pointing to the correct memory to obtain the length of the string.
Quote
*end is a pointer to the end of the string yes?
A pointer to the memory immediately following the memory block for the
characters, yes.
Quote
You don't declare *end or *ptr
Yes, I am. What I showed you earlier are fully valid declarations.
Quote
Or do char *end/*ptr have some specific meaning in C++
Of course they do. They declare pointers to values of type 'char'. That is
what the asterik is doing - declaring a pointer. Perhaps you will
understand this instead:
char* ptr = thisText.c_str();
char* end = ptr + thisText.Length();
Notice the difference? The asterik has moved now, but the meaning is
exactly the same as before. In most cases, whitespace in statements does
not matter. All of the following are identical:
char* ptr = thisText.c_str();
char *ptr = thisText.c_str();
char*ptr=thisText.c_str();
char * ptr = thisText.c_str();
Quote
Not sure of the difference between ptr and *ptr and end
and *end - one is a value and the other a pointer
No, they are all pointers.
Quote
Presumably I could use c_str() to create a function to convert
between string and String - you think????
You don't need a function. Just assign them directly:
String s1 = "whatever";
std::string s2 = s1.c_str();
s1 = s2.c_str();
Gambit
 

Re:string, String and AnsiString - lost in a sea of confusion

On Wed, 2 Mar 2005 11:03:42 -0800, "Remy Lebeau \(TeamB\)"
< XXXX@XXXXX.COM >wrote:
Quote

"Marshal Anderson [Novice]" < XXXX@XXXXX.COM >
wrote in message news: XXXX@XXXXX.COM ...


>>char *ptr = thisText.c_str();
>OK - so you create a character array from thisText and *ptr points to
>the start of it.

No, I am not creating any array at all. The String already contains an
array of characters. I am simply declaring a pointer that point to the
start of that existing memory.
<SNIPPED LOTS OF USEFUL STUFF>
Just wanted to say thanks for the time you put into that reply.
Marshal