Discussion:
How to concatenate STL strings
(too old to reply)
Pete Fraser
2008-06-11 08:42:48 UTC
Permalink
Having been used to AnsiStrings, I'm trying to now use std:string and am
having problems.
What is the correct method to concatenate strings?

e.g. this is what I want to do:
std::string File = "MyFile";
std::String Path = "c:/MyPath/MySubPath/";
remove(Path+File);

but the concatenation on the last line won't compile (as no operator = for
string class)
Thanks, Pete
Alan Bellingham
2008-06-11 09:15:47 UTC
Permalink
Post by Pete Fraser
Having been used to AnsiStrings, I'm trying to now use std:string and am
having problems.
What is the correct method to concatenate strings?
std::string File = "MyFile";
std::String Path = "c:/MyPath/MySubPath/";
remove(Path+File);
but the concatenation on the last line won't compile (as no operator = for
string class)
Is that exactly as typed? I mean, did you really refer to the
non-existent std::String?

You may have ended up trying to append an AnsiString (which gets aliased
to String-with-a-capital-S) to a standard string-with-a-lower-case-s.

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Pete Fraser
2008-06-11 09:28:50 UTC
Permalink
no that's a typo!
Pete
Post by Alan Bellingham
Post by Pete Fraser
Having been used to AnsiStrings, I'm trying to now use std:string and am
having problems.
What is the correct method to concatenate strings?
std::string File = "MyFile";
std::String Path = "c:/MyPath/MySubPath/";
remove(Path+File);
but the concatenation on the last line won't compile (as no operator = for
string class)
Is that exactly as typed? I mean, did you really refer to the
non-existent std::String?
You may have ended up trying to append an AnsiString (which gets aliased
to String-with-a-capital-S) to a standard string-with-a-lower-case-s.
Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Alan Bellingham
2008-06-11 09:39:39 UTC
Permalink
Post by Pete Fraser
no that's a typo!
Well, the following compiles:

#include <string>
#include <cstdlib>

int main()
{
std::string File = "MyFile";
std::string Path = "c:/MyPath/MySubPath/";
std::remove((Path+File).c_str());
}

Note that remove() wants a const char*, so the use of the c_str() method
is needed. For safety reasons, std::string does *not* silently convert
to const char*.

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Duane Hebert
2008-06-11 12:55:44 UTC
Permalink
Post by Alan Bellingham
Post by Pete Fraser
no that's a typo!
#include <string>
#include <cstdlib>
int main()
{
std::string File = "MyFile";
std::string Path = "c:/MyPath/MySubPath/";
std::remove((Path+File).c_str());
}
Note that remove() wants a const char*, so the use of the c_str() method
is needed. For safety reasons, std::string does *not* silently convert
to const char*.
Any idea why most of the file handling routines (fstream etc.)
take const char* instead of std::string?
Chris Uzdavinis (TeamB)
2008-06-11 13:18:55 UTC
Permalink
Post by Duane Hebert
Any idea why most of the file handling routines (fstream etc.)
take const char* instead of std::string?
strings can be easily converted into char const *, but to change the
stream interfaces to take strings would break countless millions of
lines of code.

Further, it would needleslly couple the code, and including <string>
pulls in quite a bit of source. It can only use dynamic allocation
and must copy the argument, so that tends to be a slow way to pass
"string data" to functions.

Since things were already in place, I think the overall attitude was
to leave somethig that is "good-enough" alone.

If C++ were to be designed from the ground up today, my guess is that
strings would be a built-in type, or at least have more support to
pass them around "cheaply".
--
Chris (TeamB);
Alan Bellingham
2008-06-11 13:38:45 UTC
Permalink
Post by Chris Uzdavinis (TeamB)
Post by Duane Hebert
Any idea why most of the file handling routines (fstream etc.)
take const char* instead of std::string?
It would make sense to accept std::string *as well as* char const*,
agreed. 'Instead of' would be a bad idea.
Post by Chris Uzdavinis (TeamB)
strings can be easily converted into char const *, but to change the
stream interfaces to take strings would break countless millions of
lines of code.
If it were being extended to accept std::string as well as char const*,
it probably wouldn't be too bad, though some code would break (anything
where a cast operator could return either std::string or char const* -
arguably such code would be broken anyway).

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Duane Hebert
2008-06-11 16:58:34 UTC
Permalink
Post by Alan Bellingham
Post by Chris Uzdavinis (TeamB)
Post by Duane Hebert
Any idea why most of the file handling routines (fstream etc.)
take const char* instead of std::string?
It would make sense to accept std::string *as well as* char const*,
agreed. 'Instead of' would be a bad idea.
Post by Chris Uzdavinis (TeamB)
strings can be easily converted into char const *, but to change the
stream interfaces to take strings would break countless millions of
lines of code.
If it were being extended to accept std::string as well as char const*,
it probably wouldn't be too bad, though some code would break (anything
where a cast operator could return either std::string or char const* -
arguably such code would be broken anyway).
Yes, I meant "as well as".
Eliot Frank
2008-06-11 14:15:17 UTC
Permalink
Post by Chris Uzdavinis (TeamB)
Post by Duane Hebert
Any idea why most of the file handling routines (fstream etc.)
take const char* instead of std::string?
strings can be easily converted into char const *, but to change the
stream interfaces to take strings would break countless millions of
lines of code.
Further, it would needleslly couple the code, and including <string>
pulls in quite a bit of source. It can only use dynamic allocation
and must copy the argument, so that tends to be a slow way to pass
"string data" to functions.
I believe I read somewhere (but can't find a reference now) that there
is a proposal or revision pending in committee to do just that, have
fstream() and fstream::open() take string (const &) arguments (in fact
to revise all standard library functions that take char const * to take
string const & arguments). I don't see how that would "break countless
millions of lines of code".

"pulls in quite a bit of source" ... and iostreams doesn't? (From my
perusal of the dinkumware includes, both fstream and string pull in
istream and all its ilk.)

"a slow way to pass 'string data' to functions" ... slow compared to
what, opening a file (and reading/writing data)? I rather doubt that.

-Eliot
Chris Uzdavinis (TeamB)
2008-06-11 17:49:37 UTC
Permalink
Post by Eliot Frank
I believe I read somewhere (but can't find a reference now) that there
is a proposal or revision pending in committee to do just that, have
fstream() and fstream::open() take string (const &) arguments (in fact
to revise all standard library functions that take char const * to
take string const & arguments).
Actually, the interest is in accepting wide-character filenames, and
they just threw in the idea of using std::string args as well.

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#454

In a duplicate defect report, someone requested std::string and
wchar_t* constructor args, and the reply was:

"This is not a defect in the Standard. It might be an interesting
extension for the next Standard."
Post by Eliot Frank
I don't see how that would "break countless millions of lines of
code".
I was thinking that the char pointer constructor for std::string was
declared explicit, and then code that provides char * arguments
wouldn't work. It turns out that this constructor is not excplicit,
so my concern was unfounded. But, since it was clairified that the
request was to "support" std::string in addition to raw pointers, then
it would be less of a problem, but as Alan pointed out, there would be
new sources of ambiguities when code can convert to either.
Post by Eliot Frank
"pulls in quite a bit of source" ... and iostreams doesn't? (From my
perusal of the dinkumware includes, both fstream and string pull in
istream and all its ilk.)
Sorry, but I don't buy this argument. Pulling in "a lot" is
unfortunate, and should not be justification for making matters worse.
Post by Eliot Frank
"a slow way to pass 'string data' to functions" ... slow compared to
what, opening a file (and reading/writing data)? I rather doubt that.
If you have data in a char*, I'd rather not have to allocate new
buffers and copy them just for the sake of satisfying the interface
type. You could argue that files are a special case, since presumably
they're not opened that often, but as a general rule, creating string
objects is one subtle yet common way to introduce performance problems
into an application. (Especially when this is frequently done.)
--
Chris (TeamB);
Duane Hebert
2008-06-11 19:17:14 UTC
Permalink
Post by Chris Uzdavinis (TeamB)
If you have data in a char*, I'd rather not have to allocate new
buffers and copy them just for the sake of satisfying the interface
type. You could argue that files are a special case, since presumably
they're not opened that often, but as a general rule, creating string
objects is one subtle yet common way to introduce performance problems
into an application. (Especially when this is frequently done.)
But I don't tend to have char* in my code any more so it's
more a matter of having a string and being required to
call the c_str() to use fstream::open() for example. Not a
big deal but I was just curious as to why there weren't overloads
taking std::string.
Hendrik Schober
2008-06-12 11:33:09 UTC
Permalink
Post by Chris Uzdavinis (TeamB)
[...]
If C++ were to be designed from the ground up today, my guess is that
strings would be a built-in type [...]
I very much doubt this. Stroustrup's bias towards
extending C++ through libraries rather than through
extending the language itself still has an enormous
influence on C++.

Schobi
Chris Uzdavinis (TeamB)
2008-06-12 13:58:46 UTC
Permalink
Post by Hendrik Schober
Post by Chris Uzdavinis (TeamB)
[...]
If C++ were to be designed from the ground up today, my guess is that
strings would be a built-in type [...]
I very much doubt this. Stroustrup's bias towards
extending C++ through libraries rather than through
extending the language itself still has an enormous
influence on C++.
True. I agree with that position as well. What I wonder is if that
was original philosophy, or one that he adopted relatively late in the
C++ lifecycle.

Since we have a deeply entrenched, working language today (more or
less), changes to the core language are much harder to justify than
library changes. Each change must clearly show improvements without
any (or with minimal) harm to existing code. Library changes,
however, generally won't affect anyone who opts not to use them. This
is therefore a cautions position to take in preserving backwards
compatibility, and is very reasonable, given where C++ is.

However, if given a clean slate with no legacy to support, I wonder
how C++ as a language would emerge if it started today.
--
Chris (TeamB);
Hendrik Schober
2008-06-12 14:39:41 UTC
Permalink
Post by Chris Uzdavinis (TeamB)
Post by Hendrik Schober
Post by Chris Uzdavinis (TeamB)
[...]
If C++ were to be designed from the ground up today, my guess is that
strings would be a built-in type [...]
I very much doubt this. Stroustrup's bias towards
extending C++ through libraries rather than through
extending the language itself still has an enormous
influence on C++.
True. I agree with that position as well. What I wonder is if that
was original philosophy, or one that he adopted relatively late in the
C++ lifecycle.
ISTR that he wrote somewhere that he welcomed the stream
library (the original one, by Jerry Schwartz, IIRC), as
it shows that completely type-safe IO could be done in a
library in C++. AFAIR the original stream lib was written
in the early 80ies, so that philosophy is 25 years old or
older.
Post by Chris Uzdavinis (TeamB)
[...]
However, if given a clean slate with no legacy to support, I wonder
how C++ as a language would emerge if it started today.
I don't have anything to quote now, but ISTR that I've
read several interviews with Stroustrup where he said
something about minor details he'd do different, but in
the whole would do the same again.

Schobi

Bob Gonder
2008-06-11 13:22:02 UTC
Permalink
Post by Duane Hebert
Post by Alan Bellingham
Note that remove() wants a const char*, so the use of the c_str() method
is needed. For safety reasons, std::string does *not* silently convert
to const char*.
Any idea why most of the file handling routines (fstream etc.)
take const char* instead of std::string?
Probably because "filename.dat" isn't a std::string.
It is cheaper to demote a string to char* than
promote a char* to a temporary string.
Bob Gonder
2008-06-11 13:26:00 UTC
Permalink
Post by Bob Gonder
Post by Alan Bellingham
Note that remove() wants a const char*, so the use of the c_str() method
Probably because "filename.dat" isn't a std::string.
It is cheaper to demote a string to char* than
promote a char* to a temporary string.
Rats, button slip...
Also was going to mention that remove() is a C function.
Pete Fraser
2008-06-12 10:04:31 UTC
Permalink
I think my problem was not #including <string>
Once you do that it works as expected.
Oh well...
Pete
Post by Alan Bellingham
Post by Pete Fraser
no that's a typo!
#include <string>
#include <cstdlib>
int main()
{
std::string File = "MyFile";
std::string Path = "c:/MyPath/MySubPath/";
std::remove((Path+File).c_str());
}
Remy Lebeau (TeamB)
2008-06-11 16:25:57 UTC
Permalink
Post by Pete Fraser
Having been used to AnsiStrings, I'm trying to now use std:string
and am having problems.
What is the correct method to concatenate strings?
The same way you do with AnsiString - use the '+' operator, exactly as you
are already doing.
Post by Pete Fraser
remove(Path+File);
remove() expects a char*, not a std::string or an AnsiString:

remove((Path+File).c_str());

or:

std::string File = "MyFile";
std::string Dir = "c:/MyPath/MySubPath/";
std::string Path = Dir + File;
remove(Path.c_str());


Gambit
Loading...