Topic: std::string and null terminator


Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Fri, 19 Oct 2001 10:26:13 GMT
Raw View
>
> Why not use iterators?
>   func(c_str, c_str + strlen(c_str));
>   func(cpp_str.begin(), cpp_str.end());

because strlen GOES THROUGH the string to compute the length, so you'd
process the string twice.
--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Mon, 15 Oct 2001 17:20:09 GMT
Raw View
Suppose you have a function like:

template <typename STRING_T>
void func(STRING_T s)
{
    // now cycle over all the chars of 's'
}



if STRING_T == char*, you can write:

int i = 0;
while ( s[i] != 0 )
{
    // do something
    i++;
}


but this (in my compiler) works even when STRING_T == std::string.
I guess in my implementation, string does contain a *null-terminated*
array/vector/container of chars.

does the standard says anything?
or is there a better way to code the loop *WITHOUT* passing the string
length in advance?
--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: jtbell@presby.edu (Jon Bell)
Date: Mon, 15 Oct 2001 18:16:13 GMT
Raw View
In article <YIxy7.20052$1H1.1581824@news.infostrada.it>,
Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote:
>
>if STRING_T == char*, you can write:
>
>int i = 0;
>while ( s[i] != 0 )
>{
>    // do something
>    i++;
>}
>
>
>but this (in my compiler) works even when STRING_T == std::string.
>I guess in my implementation, string does contain a *null-terminated*
>array/vector/container of chars.

That might very well be the case with your compiler.

>does the standard says anything?

I don't think so.

>or is there a better way to code the loop *WITHOUT* passing the string
>length in advance?

If you're passing a std::string, you're *already* passing the string
length along with it anyway.  Use the size() or length() member function
to get at it:

for (int i = 0; i < s.size(); ++i)
{
  // do somwthing with s[i]
]

--
Jon Bell <jtbell@presby.edu>                        Presbyterian College
Dept. of Physics and Computer Science        Clinton, South Carolina USA

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Anton Ragnarsson" <antonr@funcom.com>
Date: Mon, 15 Oct 2001 19:43:06 GMT
Raw View
"Mycroft Holmes" <holmes@technologist.REMOVEME.com> wrote:
> Suppose you have a function like:
>
> but this (in my compiler) works even when STRING_T == std::string.
> I guess in my implementation, string does contain a *null-terminated*
> array/vector/container of chars.
>
> does the standard says anything?

nopes, doesn't have to be zero-terminated, but:
"std::string::c_str()" will give you a zero-terminated c-style string.

.anton


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Al Thorpe" <al.thorpe@grassvalleygroup.com>
Date: Tue, 16 Oct 2001 14:40:54 GMT
Raw View
The string class does have an operator[] which returns the character at the
index position. The returned valid is undefined for invalid indexes, but the
position after the last valid character is considered valid and the return
value is '\0'. Effectively, it emulates the way a char * would work. This is
why your code works.

I found this on page 487 of "The Standard C++ Library" by Nicolai M.
Josuttis, an excellent book on the library.

Al


"Mycroft Holmes" <holmes@technologist.REMOVEME.com> wrote in message
news:YIxy7.20052$1H1.1581824@news.infostrada.it...
> Suppose you have a function like:
>
> template <typename STRING_T>
> void func(STRING_T s)
> {
>     // now cycle over all the chars of 's'
> }
>
>
>
> if STRING_T == char*, you can write:
>
> int i = 0;
> while ( s[i] != 0 )
> {
>     // do something
>     i++;
> }
>
>
> but this (in my compiler) works even when STRING_T == std::string.
> I guess in my implementation, string does contain a *null-terminated*
> array/vector/container of chars.
>
> does the standard says anything?
> or is there a better way to code the loop *WITHOUT* passing the string
> length in advance?
> --
>  The set of solutions is never empty.
>  Two solutions together form a new problem.
> -- Mycroft Holmes
>
> ---
> [ 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://www.research.att.com/~austern/csc/faq.html                ]
>


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Tue, 16 Oct 2001 16:40:36 GMT
Raw View
> If you're passing a std::string, you're *already* passing the string
> length along with it anyway.  Use the size() or length() member function
> to get at it:
>
> for (int i = 0; i < s.size(); ++i)
> {
>   // do somwthing with s[i]
> ]
>

this is exactly the thing I must avoid: yes, *I know* I'm passing the
length, but the template-program doesn't know, so it cannot call size(). try

template <class T1>
void func(T1 s)
{
    s.size();
}

and call func(char*)...
--
 The set of solutions is never empty.
 Two solutions together form a new problem.
--

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Ron Natalie <ron@sensor.com>
Date: Tue, 16 Oct 2001 16:40:57 GMT
Raw View

Al Thorpe wrote:
>
> The string class does have an operator[] which returns the character at the
> index position. The returned valid is undefined for invalid indexes, but the
> position after the last valid character is considered valid and the return
> value is '\0'. Effectively, it emulates the way a char * would work. This is
> why your code works.

Be very, very, careful.  There are two operator[]'s.  One is const, the other
isn't.  Only the const one has the idiotic provision that acessing string[size()]
returns charT().  Note that in the original example, the string used is NOT const
so the non-const operator[] is used and hence acessing string[size()] is UNDEFINED
BEHAVIOR.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Tue, 16 Oct 2001 18:20:52 GMT
Raw View
Mycroft Holmes wrote:
>
> > If you're passing a std::string, you're *already* passing the string
> > length along with it anyway.  Use the size() or length() member function
> > to get at it:
> >
> > for (int i = 0; i < s.size(); ++i)
> > {
> >   // do somwthing with s[i]
> > ]
> >
>
> this is exactly the thing I must avoid: yes, *I know* I'm passing the
> length, but the template-program doesn't know, so it cannot call size(). try
>
> template <class T1>
> void func(T1 s)
> {
>     s.size();
> }
>
> and call func(char*)...

But char* is always peculiar. So provide a specialization. But better to
use iterators, so the real work is done in just one place, and then a
char* specialization that passes iterators to the general version.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Colin Rafferty <colin@xemacs.org>
Date: Tue, 16 Oct 2001 18:35:39 GMT
Raw View
Mycroft Holmes wrote:

>> If you're passing a std::string, you're *already* passing the
>> string length along with it anyway.  Use the size() or length()
>> member function to get at it:

> this is exactly the thing I must avoid: yes, *I know* I'm passing
> the length, but the template-program doesn't know, so it cannot call
> size(). try

Why not use iterators?

  template <class It>
  void func(It begin, It end)
  { /* ... */ }

Then you can call it correctly:

  func(c_str, c_str + strlen(c_str));

or

  func(cpp_str.begin(), cpp_str.end());

--
Colin

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: jtbell@presby.edu (Jon Bell)
Date: Tue, 16 Oct 2001 19:46:30 GMT
Raw View
In article <rkUy7.27907$1H1.2526573@news.infostrada.it>,
Mycroft Holmes <holmes@technologist.REMOVEME.com> wrote:
>
>> If you're passing a std::string, you're *already* passing the string
>> length along with it anyway.  Use the size() or length() member function
>> to get at it:
>>
>> for (int i = 0; i < s.size(); ++i)
>> {
>>   // do somwthing with s[i]
>> ]
>>
>
>this is exactly the thing I must avoid: yes, *I know* I'm passing the
>length, but the template-program doesn't know, so it cannot call size(). try

Why use a template function?  Write two (overloaded) versions of your
function, with the same name, one taking a char* as its argument, the
other taking a std::string as its argument.  The compiler will know which
one to use in each case by examining the arguments that you pass in the
function call.

--
Jon Bell <jtbell@presby.edu>                        Presbyterian College
Dept. of Physics and Computer Science        Clinton, South Carolina USA

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]