By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,956 Members | 1,457 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,956 IT Pros & Developers. It's quick & easy.

does std::string have something like CString::GetBuffer?

P: n/a
sas
hi,

i need that because the path functions for windows, like PathAppend
and PathRemoveFileExt accept a writable zero terminated char*, but i
didn't find that for std::string, with CString, i usually use
GetBuffer for that

LPTSTR CString::GetBuffer( int nMinBufLength )
Jun 27 '08 #1
Share this Question
Share on Google+
12 Replies


P: n/a
On Fri, 30 May 2008 03:43:45 -0700, sas wrote:
hi,

i need that because the path functions for windows, like PathAppend and
PathRemoveFileExt accept a writable zero terminated char*, but i didn't
find that for std::string, with CString, i usually use GetBuffer for
that

LPTSTR CString::GetBuffer( int nMinBufLength )
const char* std::string::c_str() const

--
Lionel B
Jun 27 '08 #2

P: n/a
sas
On May 30, 2:23*pm, Lionel B <m...@privacy.netwrote:
On Fri, 30 May 2008 03:43:45 -0700, sas wrote:
hi,
i need that because the path functions for windows, like PathAppend and
PathRemoveFileExt accept a writable zero terminated char*, but i didn't
find that for std::string, with CString, i usually use GetBuffer for
that
LPTSTR CString::GetBuffer( int nMinBufLength )

const char* std::string::c_str() const

--
Lionel B
c_str doesn't work for me, because it returns a const, i want to be
able to pass the raw zero-terminated buffer to a C function that
changes it, then tell the string object to update with the new
sequence.

for example:

int a = 5;
CString str;
char* buffer = str.GetBuffer(MAX_PATH);
sprintf(buffer, "var = %d", a);
str.ReleaseBuffer();

str is now "var = 5"

with string i have to do this:

int a = 5;
std::string str;
char buffer[MAX_PATH];
strcpy(buffer, str.c_str());
sprintf(buffer, "var = %d", a);
str = buffer;

i have to use an additional buffer for std::string
Jun 27 '08 #3

P: n/a
On Fri, 30 May 2008 05:41:45 -0700, sas wrote:
On May 30, 2:23Â*pm, Lionel B <m...@privacy.netwrote:
>On Fri, 30 May 2008 03:43:45 -0700, sas wrote:
hi,
i need that because the path functions for windows, like PathAppend
and PathRemoveFileExt accept a writable zero terminated char*, but i
didn't find that for std::string, with CString, i usually use
GetBuffer for that
LPTSTR CString::GetBuffer( int nMinBufLength )

const char* std::string::c_str() const

--
Lionel B
^^^^^^^^
(please don't quote sigs)
c_str doesn't work for me, because it returns a const, i want to be able
to pass the raw zero-terminated buffer to a C function that changes it,
then tell the string object to update with the new sequence.
No, sure. You can't "write to the c_str()" of a std::string. It's part of
the internals of a std::string and is definitely read-only and not to be
messed about with; hence the const.
for example:

int a = 5;
CString str;
char* buffer = str.GetBuffer(MAX_PATH); sprintf(buffer, "var = %d", a);
str.ReleaseBuffer();

str is now "var = 5"

with string i have to do this:

int a = 5;
std::string str;
char buffer[MAX_PATH];
strcpy(buffer, str.c_str());
^^^^^^^^^^^^^^^^^^^^^^^^^^^

This looks dangerous (does it even compile?) and is pointless anyway,
since you later set string = buffer. Just leave it out.
sprintf(buffer, "var = %d", a);
str = buffer;

i have to use an additional buffer for std::string
Yes you do indeed if you want to update a std::string from a C-style
string. In fact there's no guarantee that a std::string is even
implemented with anything like a char buffer, zero-terminated or
otherwise.

--
Lionel B
Jun 27 '08 #4

P: n/a
On Fri, 30 May 2008 05:41:45 -0700, sas wrote:
* sas:
>>
with string i have to do this:

int a = 5;
std::string str;
char buffer[MAX_PATH];
strcpy(buffer, str.c_str());
sprintf(buffer, "var = %d", a);
str = buffer;

i have to use an additional buffer for std::string
On Fri, 30 May 2008 13:04:21 +0000, Lionel B wrote:
Yes you do indeed if you want to update a std::string from a C-style
string. In fact there's no guarantee that a std::string is even
implemented with anything like a char buffer, zero-terminated or
otherwise.
On Fri, 30 May 2008 15:08:28 +0200, Alf P. Steinbach wrote:
No, you don't.

With std::string you can use resize() to allocate a suitably large
buffer, and &s[0] to get a pointer to the internal buffer.
I stand corrected. I wasn't aware that it was ever safe to write to the
internal buffer of a std::string.

--
Lionel B
Jun 27 '08 #5

P: n/a
Lionel B wrote:
>On Fri, 30 May 2008 05:41:45 -0700, sas wrote:
>* sas:
>>>
with string i have to do this:

int a = 5;
std::string str;
char buffer[MAX_PATH];
strcpy(buffer, str.c_str());
sprintf(buffer, "var = %d", a);
str = buffer;

i have to use an additional buffer for std::string

On Fri, 30 May 2008 13:04:21 +0000, Lionel B wrote:
>Yes you do indeed if you want to update a std::string from a C-style
string. In fact there's no guarantee that a std::string is even
implemented with anything like a char buffer, zero-terminated or
otherwise.

On Fri, 30 May 2008 15:08:28 +0200, Alf P. Steinbach wrote:
>No, you don't.

With std::string you can use resize() to allocate a suitably large
buffer, and &s[0] to get a pointer to the internal buffer.

I stand corrected. I wasn't aware that it was ever safe to write to the
internal buffer of a std::string.
It isn't yet. However, C++0X will guarantee that std::string is contiguous
in memory. Then, it will be legal to write into the buffer. Until then, it
will just be safe since all popular implementations of std::string already
are contiguous. (However, last time I checked, C++0x was not slated to
guarantee that there is a memory position for a terminating 0 char. So, you
need to take that into account when allocating the buffer.)
Best

Kai-Uwe Bux
Jun 27 '08 #6

P: n/a
On May 30, 7:23 am, Lionel B <m...@privacy.netwrote:
On Fri, 30 May 2008 03:43:45 -0700, sas wrote:
i need that because the path functions for windows, like PathAppend and
PathRemoveFileExt accept a writable zero terminated char*, but i didn't
find that for std::string, with CString, i usually use GetBuffer for
that
LPTSTR CString::GetBuffer( int nMinBufLength )

const char* std::string::c_str() const
I don't think this fits the OP's requirements. CString::GetBuffer(int)
returns a *writable* buffer, and the caller can request a minimal size
for the buffer.
Jun 27 '08 #7

P: n/a
sas
On May 30, 4:08*pm, "Alf P. Steinbach" <al...@start.nowrote:
* * * * *s.resize( sprintf( &s[0], "var = %d", a ) );
nice code :)
took me a while to figure it out

i wanted to use std::string with PathAppend,
here is a definition of PathAppend from msdn:

PathAppend Function

Appends one path to the end of another.

Syntax

BOOL PathAppend(
LPTSTR pszPath,
LPCTSTR pszMore
);

Parameters

pszPath
[in, out] A pointer to a null-terminated string to which the
path specified in pszMore is appended. You should set the size of this
buffer to MAX_PATH to ensure that it is large enough to hold the
returned string.
pszMore
[in] A pointer to a null-terminated string of maximum length
MAX_PATH that contains the path to be appended.

Return Value

Returns TRUE if successful, or FALSE otherwise.

Remarks

This function automatically inserts a backslash between the two
strings, if one is not already present.

The path supplied in pszPath cannot begin with "..\\" or ".\\" to
produce a relative path string. If present, those periods are stripped
from the output string. For example, appending "path3" to "..\\path1\
\path2" results in an output of "\path1\path2\path3" rather than "..
\path1\path2\path3".
so this function appends one string to another, and it expects to find
a trailing zero, unlike sprintf

i know c_str() appends a zero (temporary), and i can use resize to set
string to MAX_PATH, but there's no way afaik to notify it that the
controlled sequence is updated so it should re-read it

so there's no way to avoid that additional buffer
Jun 27 '08 #8

P: n/a
Sam
sas writes:
c_str doesn't work for me, because it returns a const, i want to be
able to pass the raw zero-terminated buffer to a C function that
changes it, then tell the string object to update with the new
sequence.
There is no equivalent functionality in std::string. You can achieve the
same functionality by using the append() method to resize the string to the
required size, and then using std::string's iterators to mess around with
its contents.

I know what you're talking about, and there is no direct equivalent in
std::string, and it's a good thing. MFC's sloppy class design opens many
opportunities for coding errors, like buffer overflows and stack smashing,
that leads to security holes. You will find out that using the C++ library
and STL containers correctly leads to good programming practices that
eliminates nearly all opportunities for coding errors of this nature.

A long time ago before C++ STL matured, I've cobbled together fairly
significant bits of code that, due to the lack of reliable multiplatform
availability of the C++ STL, included reimplementations of various MFC
classes, like CString, CArray, CList, and others. They were more simpler to
reimplement than the STL. Last year, finally, I replaced the last remaining
bits of that ugly code with a pure C++ STL implementation. And I feel so
much better now.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEABECAAYFAkhAh+YACgkQx9p3GYHlUOI7JACeIWXCNpWTsc lR3Hew5bUeAt0P
nNsAn3afuPGixygjiKGvPi9Lq5IazoC1
=hL1c
-----END PGP SIGNATURE-----

Jun 27 '08 #9

P: n/a
Sam wrote:
sas writes:
>c_str doesn't work for me, because it returns a const, i want to be
able to pass the raw zero-terminated buffer to a C function that
changes it, then tell the string object to update with the new
sequence.

There is no equivalent functionality in std::string. You can achieve the
same functionality by using the append() method to resize the string to
the required size, and then using std::string's iterators to mess around
with its contents.

I know what you're talking about, and there is no direct equivalent in
std::string, and it's a good thing. MFC's sloppy class design opens many
opportunities for coding errors, like buffer overflows and stack smashing,
that leads to security holes. You will find out that using the C++ library
and STL containers correctly leads to good programming practices that
eliminates nearly all opportunities for coding errors of this nature.
I am not so sure whether std::string is well designed in this regard. As far
as I can see,

str[huge_number] = 'c';

is just as prone to buffer overflows and stack corruption as anything else.
Now, of course, you can say that is using std::string _incorrectly_. But
that defense can be mounted for any class that is designed with documented
undefined behavior. By and large, safety seems not to be a major concern in
the design of the STL and there is undefined behavior lurking around every
corner.
[snip]

Best

Kai-Uwe Bux
Jun 27 '08 #10

P: n/a
On May 30, 3:29 pm, "Alf P. Steinbach" <al...@start.nowrote:
* Lionel B:
On Fri, 30 May 2008 05:41:45 -0700, sas wrote:
* sas:
with string i have to do this:
>int a = 5;
std::string str;
char buffer[MAX_PATH];
strcpy(buffer, str.c_str());
sprintf(buffer, "var = %d", a);
str = buffer;
>i have to use an additional buffer for std::string
On Fri, 30 May 2008 13:04:21 +0000, Lionel B wrote:
Yes you do indeed if you want to update a std::string from
a C-style string. In fact there's no guarantee that a
std::string is even implemented with anything like a char
buffer, zero-terminated or otherwise.
On Fri, 30 May 2008 15:08:28 +0200, Alf P. Steinbach wrote:
No, you don't.
With std::string you can use resize() to allocate a
suitably large buffer, and &s[0] to get a pointer to the
internal buffer.
I stand corrected. I wasn't aware that it was ever safe to
write to the internal buffer of a std::string.
Well it wasn't, formally, at one time.
Officially, it still isn't, formally. The 0x version of C++ has
not yet been formally adapted:-). Practically, of course, it's
exactly as you say.

Note that the next version of the standard will also provide
cleaner ways of doing this: a non-const version of data() (for
both std::string and std::vector), rather than &s[0].

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #11

P: n/a
On May 31, 9:40 am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Sam wrote:
sas writes:
c_str doesn't work for me, because it returns a const, i
want to be able to pass the raw zero-terminated buffer to a
C function that changes it, then tell the string object to
update with the new sequence.
There is no equivalent functionality in std::string. You
can achieve the same functionality by using the append()
method to resize the string to the required size, and then
using std::string's iterators to mess around with its
contents.
I know what you're talking about, and there is no direct
equivalent in std::string, and it's a good thing. MFC's
sloppy class design opens many opportunities for coding
errors, like buffer overflows and stack smashing, that leads
to security holes. You will find out that using the C++
library and STL containers correctly leads to good
programming practices that eliminates nearly all
opportunities for coding errors of this nature.
I am not so sure whether std::string is well designed in this
regard. As far as I can see,
str[huge_number] = 'c';
is just as prone to buffer overflows and stack corruption as
anything else.
It's a quality of implementation issue. With the better
implementations I use (g++, VC++), this will cause a program
crash. With the poorer ones, it will corrupt the free space
arena (which also leads to a program crash down the line). I've
never seen an implementation where it would corrupt the stack,
or where it could effectively be used to breech security,
however.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #12

P: n/a
Hi!

Kai-Uwe Bux schrieb:
By and large, safety seems not to be a major concern in
the design of the STL and there is undefined behavior lurking around every
corner.
At least the STL is not designed to work well with MFC! For my part, I'm
happy I don't need these ugly
please-append-my-platform-path-separator-to-my-string-if-its-not-already-there
function or the like. I've discovered boost::path, which does that for
me automatically.

Frank
Jun 27 '08 #13

This discussion thread is closed

Replies have been disabled for this discussion.