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

S

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 )
 
L

Lionel B

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
 
S

sas

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

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
 
L

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.
 
L

Lionel B

* 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

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.

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.
 
K

Kai-Uwe Bux

Lionel said:
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

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.

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
 
E

Eric.Malenfant

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.
 
S

sas

         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
 
K

Kai-Uwe Bux

Sam said:
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
 
J

James Kanze

* Lionel B:
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
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.
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].
 
J

James Kanze

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.
 
F

Frank Birbacher

Hi!

Kai-Uwe Bux said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top