Topic: fstream constructor taking string argument?


Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1998/09/08
Raw View
Dave Steffen <steffend@helicon.physics.colostate.edu> writes:

> The question remains, why we don't have open(string) in the
> library? Oversight? Or is there some issue here that I don't
> understand?

I don't think anyone suggested it until a rather late stage of the
standardization process, at which point it was deemed already too late.
I don't know if there was ever any formal proposal for it -- I think not.
I don't think there were any technical issues raised against it,
I think it was just a question of timing.

(That's my rather vague recollection, based on less than complete
information; it is possible that I may be wrong.)

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/08/28
Raw View
Hans Aberg<haberg@REMOVE.matematik.su.se> wrote:
>
>  Make a string class which saves the length of the string but allocates
>one extra end position in which a '\0' is put. Then add an "operator const
>char() const" to this class which return the pointer to the stored string,
> ...
>  I wonder why the C++ standard does not have such a string class; it is
>sooo convenient.

It does not have such a string class because classes with
conversion operators, particularly to built-in types, create
huge holes in the type system.  Any string class which has
a programmed conversion to a pointer should be looked on with
extreme suspicion.

Convenience is not a good enough reason to destroy the C++ type
system.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.org/



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Kresimir Fresl <fresl@grad.hr>
Date: 1998/08/31
Raw View
Matt Arnold wrote:

> Siemel Naran wrote in message ...
> >
> >Only thing is, why did they call the function "c_str"?
> >Why not just call it "str", which is easier to type?

[...]
> Besides, this shouldn't be easy to type -- we want to
> make it difficult (or at least annoying) to use
> old-style "C" strings in new C++ programs.
> Everyone should be using std::string!  ;-)

So, let's return to original question:

  string file_name;
  cin >> file_name;

> we want to make it difficult

  ofstream output_file (file_name.c_str());

> to use old-style "C" strings...

> Everyone should be using std::string!  ;-)

How?


fres


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: simonlee@netcene.com
Date: 1998/08/31
Raw View
On 31 Aug 1998 14:50:03 GMT, Kresimir Fresl <fresl@grad.hr>
enlightened us with:
<snip>
>> Besides, this shouldn't be easy to type -- we want to
>> make it difficult (or at least annoying) to use
>> old-style "C" strings in new C++ programs.
>> Everyone should be using std::string!  ;-)
>
>So, let's return to original question:
>
>  string file_name;
>  cin >> file_name;
>
>> we want to make it difficult
>
>  ofstream output_file (file_name.c_str());
>
>> to use old-style "C" strings...
>
>> Everyone should be using std::string!  ;-)
>
>How?
Sorry for the "ME TOO" post, but the M$ CString class does provide a
(char*) cast operator, why not std::string?
I Agree in that "In an ideal world" we would all be using
std::string(s), but how is this possible if std::fstream contains
stuff like,

void open(const char *_S, ios_base::openmode _M = in)

??????

so where is open(std::string,ios_base::openmode)

The retort that "what if i'm using my_lib::string?" is totally
unwarranted since anyone writing a my_lib::string library would most
surely provide a (string) cast & most probably a char* cast also
(former more likely).
So what should be in std::string & std::fstream?
Easy,
The compiler treats "foo.bar" as char *, std::fstream should have an
open(const string) function NOT an open(char*). Ergo string needs
(char*) cast operator.

Next you'll be telling me that ofstream.open(foo) is faster with a
char* than a string.. but that is not the point.. right?

Simon


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/09/01
Raw View
simonlee@netcene.com wrote:
>
> On 31 Aug 1998 14:50:03 GMT, Kresimir Fresl <fresl@grad.hr>
> enlightened us with:
> <snip>
> >> Besides, this shouldn't be easy to type -- we want to
> >> make it difficult (or at least annoying) to use
> >> old-style "C" strings in new C++ programs.
> >> Everyone should be using std::string!  ;-)
> >
> >So, let's return to original question:
> >
> >  string file_name;
> >  cin >> file_name;
> >
> >> we want to make it difficult
> >
> >  ofstream output_file (file_name.c_str());
> >
> >> to use old-style "C" strings...
> >
> >> Everyone should be using std::string!  ;-)
> >
> >How?
> Sorry for the "ME TOO" post, but the M$ CString class does provide a
> (char*) cast operator, why not std::string?

Because that operator is dangerous:

extern "C" void modify(char*); // third-party function

std::string s="whatever";
char* pc=s+"more";
modify(pc);
s=pc;

Looks quite harmless, doesn't it?
However, at the call to f, pc is already a dangling pointer, since
the s+"more" generated a temporary string, and pc pointed to a char*
owned by that temporary.

> I Agree in that "In an ideal world" we would all be using
> std::string(s), but how is this possible if std::fstream contains
> stuff like,
>
> void open(const char *_S, ios_base::openmode _M = in)
>
> ??????
>
> so where is open(std::string,ios_base::openmode)

That's indeed an omission, IMHO.


> The retort that "what if i'm using my_lib::string?" is totally
> unwarranted since anyone writing a my_lib::string library would most
> surely provide a (string) cast & most probably a char* cast also
> (former more likely).

Indeed, a std::string cast would be quite useful; a char* cast
shouldn't be done, however. Besides the problem above, the
my_lib::string class would fail for every function overloaded on
char const* and std::string, if it included conversions to both,
due to ambiguity.

> So what should be in std::string & std::fstream?
> Easy,
> The compiler treats "foo.bar" as char *, std::fstream should have an
> open(const string) function NOT an open(char*). Ergo string needs
> (char*) cast operator.

IMHO std::fstream should have open(std::string) *and* open(char const*).
std::string doesn't need and shouldn't have a (char*) cast operator.

[...]



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Jim Cobban" <Jim.Cobban.jcobban@nt.com>
Date: 1998/09/01
Raw View
In article <35eae0c1.3076533@news1.newscene.com>,
 <simonlee@netcene.com> wrote:
>
>The compiler treats "foo.bar" as char *, std::fstream should have an
>open(const string) function NOT an open(char*). Ergo string needs
>(char*) cast operator.

I don't follow the "Ergo".  If std::fstream had a constructor taking const
string & instead of const char * and an open taking const string & instead
of const char *, then it seems to me, by experiment using g++, that existing
programs which assume that they can pass a char * to the std::fstream
constructor would still work.  That is the compiler would invoke the
appropriate string constructor to convert the C NUL terminated string into
the STL string to pass to std::fstream.

I don't follow the "Ergo" because:

 1) what is required is conversion from char * to string, not the other way
    around, if std::fstream took string arguments.
 2) the fact that one single application demands a conversion from string to
    char * does not demand the addition of an operator char * to the string
    type.

So since I cannot see any problem based upon reading the standard, and since
it works on at least one existing compiler without a problem, why are the
purely C++ fstream functions defined with C NUL terminated string parameters
rather than with C++ STL string parameters?

Even if, for example for efficiency, the standard is to retain the existing
methods taking C NUL terminated strings, there should be parallel methods
taking STL strings which would eliminate the necessity to use the c_str()
method when using fstreams.

--
Jim Cobban   |  jcobban@nortel.ca                   |  Phone: (613) 763-8013
Nortel (MCS) |                                      |  FAX:   (613) 763-5199


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: gv19@dial.pipex.com (simon)
Date: 1998/09/02
Raw View
On 1 Sep 1998 15:15:30 GMT, Christopher Eltschka
<celtschk@physik.tu-muenchen.de> enlightened us with:
<snip>
>> Sorry for the "ME TOO" post, but the M$ CString class does provide a
>> (char*) cast operator, why not std::string?

>Because that operator is dangerous:

>extern "C" void modify(char*); // third-party function

>std::string s="whatever";
>char* pc=s+"more";
>modify(pc);
>s=pc;

>Looks quite harmless, doesn't it?
>However, at the call to f, pc is already a dangling pointer, since
>the s+"more" generated a temporary string, and pc pointed to a char*
>owned by that temporary.

I agree ;)
A (char*) cast has the capability to fill stdlib with holes, the
example you give is more about 'bad code' than unsafe casts. Dangling
pointers/handles are never good news, & giving the programmer the
ability to use them in a stdlib would only encourage their use..
<snip>

>Indeed, a std::string cast would be quite useful; a char* cast
>shouldn't be done, however. Besides the problem above, the
>my_lib::string class would fail for every function overloaded on
>char const* and std::string, if it included conversions to both,
>due to ambiguity.
>
I think you just answered all the questions on this thread. It looks
like the stdlib authors could provide an open(char const*) _OR_ an
open(const string), this is because of the ambiguity that you mention.
The char* is the only viable choice (unless a char* cast exists in
string - same problem ) since the compiler will treat "foo.bar" as a
char*. Lowest common denominator type argument.
(Is this correct?)

Simon

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/08/27
Raw View
CD2 define constructors for ifstream/ofstream where the file name is
const char*. Since most C++ book recommend that we abandon char* for
the string class I was wondering:

* Does the actual standard define {i,o,}fstream(const string&x,...) ?
(probably as a complex template-construction, i.e.
template <class charT,class traits,class Allocator>
explicit fstream(const basic_string<charT,traits,Allocator>&x,...); )

* If not why?

Searching in comp.std.c++ I found that similar questions were asked
two years ago, no reasons against were given, and it was suggested
to start the process of putting this into the final standard.

The reason for desiring the fstream(const string&x,...) is code
such as:

const string x=...;
fstream header(x+".h");

which now requires parenthesis and .c_str().
--
// Home page  http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/27
Raw View
On 27 Aug 1998 16:22:16 GMT, Hans Olsson

>const string x=...;
>fstream header(x+".h");
>
>which now requires parenthesis and .c_str().

What happens if we're using our own string class, mystd::string?


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/27
Raw View
In article <6s35ij$t1d$1@news.lth.se>, Email_To::.Hans.Olsson@dna.lth.se
(Hans Olsson) wrote:
>The reason for desiring the fstream(const string&x,...) is code
>such as:
>
>const string x=...;
>fstream header(x+".h");
>
>which now requires parenthesis and .c_str().

  I can note that while waiting for a correction of the C++ standard in
this respect, one can define string class which is a hybrid between C
0-terminated strings and C++ strings saving the length of the string:

  Make a string class which saves the length of the string but allocates
one extra end position in which a '\0' is put. Then add an "operator const
char() const" to this class which return the pointer to the stored string,
like this
    class String
    {
    public:
        String();
        String(const char*);
        operator const char*() const;
    };

    String operator+(const String&, const char*);
If you do not use string containing \0, this will work. Then the code
might look like
    const String x;
    fstream header(x + ".h");
as you wanted.

  I wonder why the C++ standard does not have such a string class; it is
sooo convenient.

  Hans Aberg   * Anti-spam: Remove "REMOVE." from email address.
               * Email: Hans Aberg <haberg@REMOVE.member.ams.org>
               * Home Page: <http://www.matematik.su.se/~haberg/>
               * AMS member listing: <http://www.ams.org/cml/>


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/27
Raw View
On 27 Aug 1998 21:23:43 GMT, Hans Aberg <haberg@REMOVE.matematik.su.se> wrote:

>  I wonder why the C++ standard does not have such a string class; it is
>sooo convenient.

In general, implicit conversion operators lead to the wrong function
being called, ambiguity errors, etc.  All of these problems are
easily found (usually at compile time) and fixed, but they are
annoying to fix.  Furthermore, some wrong function calls will still
work, but they will lead to more inefficient programs.

// oops (error)
String s1("hello"),s2("world");
cout << s1-s2 << endl; // oops: typo: we meant s1+s2
// but it works: calls: size_t operator-(const char*, const char*)
// this particular error discovered at run time

// ok, but more inefficient program
String s("hello world"); // s.d_text="hello world", s.d_len=11
int len=s.strlen(); // just returns s.d_len, O(1)
int len=strlen(s); // calculates strlen(s.d_text), expensive to compute!


Only thing is, why did they call the function "c_str"?  Why not just
call it "str", which is easier to type?


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/08/28
Raw View
In article <slrn6ub06b.66r.sbnaran@fermi.ceg.uiuc.edu>,
Siemel Naran <sbnaran@KILL.uiuc.edu> wrote:
>
>On 27 Aug 1998 16:22:16 GMT, Hans Olsson
>
>>const string x=...;
>>fstream header(x+".h");
>>
>>which now requires parenthesis and .c_str().
>
>What happens if we're using our own string class, mystd::string?

If I understand namespaces correctly (I don't have a decent compiler here):

It wouldn't compile unless mystd::string had a conversion operator
to const char* or std::string.

The string used in the constructor should be std::string,
because the constructor was declared within namespace std.

--
// Home page  http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Matt Arnold" <marnold@garbage.com>
Date: 1998/08/28
Raw View
Siemel Naran wrote in message ...
>
>Only thing is, why did they call the function "c_str"?  Why not just
>call it "str", which is easier to type?

I believe so it would be explicit that the function gets a pointer to a "'C'
string" (a zero-terminted array of characters) and doesn't return a
std::string object (or some other kind of thing that you might take "str" to
mean).  They could have been even more explicit and called it "c_str_ptr".

Besides, this shouldn't be easy to type -- we want to make it difficult (or
at least annoying) to use old-style "C" strings in new C++ programs.
Everyone should be using std::string!  ;-)



Regards,

Matt Arnold
Professional Music Products
Mark of the Unicorn, Inc.
http://www.motu.com

/////////////////////////////////////////////////////////////////////
////////////// Change "garbage" to "motu" to email me! //////////////
/////////////////////////////////////////////////////////////////////

Pursuant to US Code, Title 47, Chapter 5, Subchapter II, Sec. 227 any
and all unsolicited commercial email sent to this address is subject
to a download and archival fee in the amount of $500.00 US.  Emailing
this address denotes acceptance of these terms.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/28
Raw View
In article <slrn6ubkob.66r.sbnaran@fermi.ceg.uiuc.edu>,
sbnaran@KILL.uiuc.edu wrote:
>In general, implicit conversion operators lead to the wrong function
>being called, ambiguity errors, etc.

  This is correct, avoid all unnecessary implicit conversions, and
especially those created by "operator T()" if possible.

  But if not possible to avoid, use them accordingly.

  So, in general, if one needs a lot of these conversions, I think one
should derive a new string class from say basic_string with an
    operator const char*() cont { return c_str(); }
added. Then this string class can be used when conversions are frequent
and later be removed when functions have been rewritten.

>Only thing is, why did they call the function "c_str"?  Why not just
>call it "str", which is easier to type?

  I think that modern programs should avoid using C-strings as far as
possible because they will break when encountering strings containing a
'\0', so it is good pointing it out.

  Hans Aberg   * Anti-spam: Remove "REMOVE." from email address.
               * Email: Hans Aberg <haberg@REMOVE.member.ams.org>
               * Home Page: <http://www.matematik.su.se/~haberg/>
               * AMS member listing: <http://www.ams.org/cml/>


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: devphil@my-dejanews.com
Date: 1998/08/28
Raw View
In article <slrn6ubkob.66r.sbnaran@fermi.ceg.uiuc.edu>,
  sbnaran@KILL.uiuc.edu wrote:

> // ok, but more inefficient program
> String s("hello world"); // s.d_text="hello world", s.d_len=11
> int len=s.strlen(); // just returns s.d_len, O(1)
> int len=strlen(s); // calculates strlen(s.d_text), expensive to compute!

I suppose that if you removed the implicit conversion operator, you could
then write (at the enclosing scope) something like

  inline int strlen (String const &s) { return s.strlen(); }

and reclaim the O(1).


> Only thing is, why did they call the function "c_str"?  Why not just
> call it "str", which is easier to type?

To make it clear that a C-style string (i.e., NUL-terminated char* (yes, I
meant NUL, not NULL :-)) is being returned.  There's another member funtion,
called data(), which returns the string being contained but is not obligated
to terminate it with a NUL character.

Luck++;
/dev/phil


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/08/28
Raw View
On 28 Aug 1998 16:58:27 GMT, devphil@my-dejanews.com

>I suppose that if you removed the implicit conversion operator, you could
>then write (at the enclosing scope) something like
>
>  inline int strlen (String const &s) { return s.strlen(); }
>
>and reclaim the O(1).

Right.  Even without the conversion operator one can write this
function.  When you say strlen(s), the best match is
strlen(String const&), and the next best match is strlen(const char*).
The best match always gets called.  It's good for efficiency.  But
if we hadn't declared strlen(String const&), the next best match
gets called.  It is reasonable for people to forget to define
the inline forwarding functions -- like the strlen(const String&)
that you have above -- which is why I think the makers of C++ did
not put in conversion operator.


>> Only thing is, why did they call the function "c_str"?  Why not just
>> call it "str", which is easier to type?

>To make it clear that a C-style string (i.e., NUL-terminated char* (yes, I
>meant NUL, not NULL :-)) is being returned.  There's another member funtion,
>called data(), which returns the string being contained but is not obligated
>to terminate it with a NUL character.

Good reason.  Coming to think of it, ostringstream::str() returns
a std::string.  If string::str() existed, it should return a
std::string, just for the parallel structure.


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]