Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > does std::string have something like CString::GetBuffer?

Reply
Thread Tools

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

 
 
sas
Guest
Posts: n/a
 
      05-30-2008
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 )
 
Reply With Quote
 
 
 
 
Lionel B
Guest
Posts: n/a
 
      05-30-2008
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
 
Reply With Quote
 
 
 
 
sas
Guest
Posts: n/a
 
      05-30-2008
On May 30, 2:23*pm, Lionel B <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
Lionel B
Guest
Posts: n/a
 
      05-30-2008
On Fri, 30 May 2008 05:41:45 -0700, sas wrote:

> On May 30, 2:23Â*pm, Lionel B <(E-Mail Removed)> wrote:
>> 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
 
Reply With Quote
 
Lionel B
Guest
Posts: n/a
 
      05-30-2008
> 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
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      05-30-2008
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
 
Reply With Quote
 
Eric.Malenfant@gmail.com
Guest
Posts: n/a
 
      05-30-2008
On May 30, 7:23 am, Lionel B <(E-Mail Removed)> wrote:
> 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.
 
Reply With Quote
 
sas
Guest
Posts: n/a
 
      05-30-2008
On May 30, 4:08*pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * * * * *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
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      05-31-2008
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
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-31-2008
On May 30, 3:29 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * 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:(E-Mail Removed)
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
can I overload operators like "=>", "->" or something like that? dmitrey Python 5 04-20-2012 05:49 PM
Re: Do Canon's competitors have something like CHDK? Time Lapse, etc? David J Taylor Digital Photography 67 09-18-2010 04:57 PM
var Something= new Something() What does it mean ? pamelafluente@libero.it Javascript 9 10-05-2006 02:43 PM
Does IOS have something like the ip-up and ip-down script in UNIX? mathias@gummert.de Cisco 2 05-19-2005 10:54 AM
Does ANSI C have something like PATHMAX or MAX_PATH? Sunner Sun C Programming 23 04-13-2004 01:19 PM



Advertisments