From: Ron Francis on
Windows XP Professional
Visual Studio 2005
Platform SDK Jan 2006
DirectX 9.0c SDK Aug 2007

I have been using char * for a long time and I have one application where
they are deeply embedded.
I have read quite a few times now that I it is better to use std:string and
today is the first time I have actually had a look at it..
One thing I would like to know is how best to handle saving a string member
in a class or struct where I have an array of them

For example, currently I have something like this ...

Class CPoint{
char text[41];
double x,y,z;
//more members and functions
}

I have an array of these points in a CArray class that I wrote myself, but
the main point is that when saving to a file, I can just save the whole
array as a block of memory (and obviously load it back into the array).
Many of the elements could be empty, but their position in the array is
important because I have other objects that are indexed to them.
So my question is, if I wanted to convert char text[41] to std:string text,
how would I best go about saving it?

Regards,
Ron Francis
www.RonaldFrancis.com




From: Nathan Mates on
In article <BKOdnT5JneB33JDVnZ2dnUVZ_jSdnZ2d(a)adnap.net.au>,
Ron Francis <ronfrancis(a)adam.com.au> wrote:
>So my question is, if I wanted to convert char text[41] to std:string text,
>how would I best go about saving it?

Straight assignment works fine. For example:

char foo[41];
strcpy_s(foo, "Hello, World!");
std::string bar;
bar = foo;

To go the other way, do

std::string bar = "Hello, World!");
char foo[41];
strcpy_s(foo, bar.c_str());

You can't blindly memcpy/fwrite or otherwise memory dump a
std::string. The current implementation (which MAY change over time!)
is that they've got a 16-byte internal class member. If the string
fits in that, it's used. If it doesn't, then it mallocs off space to
store the string, and keeps the pointer. It's all very transparent
to the user, which is why the c_str() function helps.

Nathan Mates

--
<*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
From: MS News on

> You can't blindly memcpy/fwrite or otherwise memory dump a
> std::string. The current implementation (which MAY change over time!)
> is that they've got a 16-byte internal class member. If the string
> fits in that, it's used. If it doesn't, then it mallocs off space to
> store the string, and keeps the pointer. It's all very transparent
> to the user, which is why the c_str() function helps.
>
> Nathan Mates

Pretty much what I thought.
The only way I can see to do it is loop through the array and save each one
in sequence, but that would be slow.
Looks like I'm stuck with char pointers for the time being, but what I'm
afraid of is that they will become obsolete (if not already), and I haven't
much alternative.

Cheers,
Ron.


From: Tim Roberts on
"Ron Francis" <ronfrancis(a)adam.com.au> wrote:
>
>For example, currently I have something like this ...
>
>Class CPoint{
>char text[41];
>double x,y,z;
>//more members and functions
>}
>
>I have an array of these points in a CArray class that I wrote myself, but
>the main point is that when saving to a file, I can just save the whole
>array as a block of memory (and obviously load it back into the array).
>Many of the elements could be empty, but their position in the array is
>important because I have other objects that are indexed to them.
>So my question is, if I wanted to convert char text[41] to std:string text,
>how would I best go about saving it?

You wouldn't. There's nothing inherently wrong with a character array like
that, especially if you need to save and restore them from file.
std::string is handy for manipulating strings, but only if it makes things
easier or markedly better.

The next time you do a redesign, you might consider making all of your
classes derive from some common base class that has Serialize and
Deserialize methods. Then, you can write a CPoint::Serialize that knows
how to write the object to a stream, and a CPoint::Deserialize that knows
how to recreate the object from a stream. Once you do that, you won't be
dependent on the internal format. You could change the struct to use a
std::string, as long as the Serialize function writes the length first.
--
Tim Roberts, timr(a)probo.com
Providenza & Boekelheide, Inc.
From: Alf P. Steinbach on
* Ron Francis:
>
> For example, currently I have something like this ...
>
> Class CPoint{
> char text[41];
> double x,y,z;
> //more members and functions
> }
>
> I have an array of these points in a CArray class that I wrote myself, but
> the main point is that when saving to a file, I can just save the whole
> array as a block of memory (and obviously load it back into the array).
> Many of the elements could be empty, but their position in the array is
> important because I have other objects that are indexed to them.
> So my question is, if I wanted to convert char text[41] to std:string text,
> how would I best go about saving it?

It depends on whether the text har a fixed small maximum size or not, and what
constraints are placed on the text (e.g., can there be newlines in the text?).

For a fixed small maximum size your current approach isn't bad, although a bit
unsafe.

Anyway, with a std::string in there, the preferred file format would be textual,
not binary; I'd prefer textual file as a matter of course.

With a std::string the easiest is then if the string can't contain newlines, in
which case you'd just write the string using "<<", and read it using
std::getline. Can't get more easy than that. Error checking complicates,
because the standard streams do not support exceptions (they have some support
tacked on as an afterthought, but that support is in the whole unusuable).

If the string can contain newlines then some way of knowing where a multi-line
string ends is required. One approach is then to encode the newlines, e.g. as
'\n', but then you also have to encode '\' in the string as '\\' in file. More
efficient and also easier to implement, and shorter code!, win-win-win, is then
perhaps just to first store the string length or number of lines, and read
complete lines until that string length is achieved (OK) or exceeded (error).

Cheers, & hth.,

- Alf


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?