I would like to pass such string lists around as std::string.
I'm wondering if it is legal to put nulls in std::string.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
> I'm using some libraries which use arrays of characters
> to store lists of strings woth \0 as a delimiter ( \0\0 indicates
> end of list ).
>
> I would like to pass such string lists around as std::string.
> I'm wondering if it is legal to put nulls in std::string.
Yep, it's perfectly valid for NUL characters to be in a std::string.
--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/ \ I always entertain great hopes.
\__/ Robert Frost
Church / http://www.alcyone.com/pyos/church/
A lambda calculus explorer in Python.
why not just use std::vector<char> instead? std::string is a very
special container with very special meaning. It sounds like you need
a container of characters, where 0 is not necessarily a terminator, so
why not use std::vector?
joshua lehrer
factset research systems
NYSE:FDS
No, you can't put nulls in a string. A string is an sequence of characters,
which is terminated by a null.
string s("abc\0def\0ghi") is equal to string("abc");
If you are using Windows, you can use the BSTR type. It supports embedded
nulls. It is a unicode length-prefixed "string".
See the thread named "string[index] = value"
http://groups.google.com/groups?th=e805fdec9ca4fca9
=================================
Alex Vinokur
mailto:ale...@connect.to
http://www.simtel.net/pub/oth/19088.html
=================================
Yup, fine.
Stephen Howe
Sure, but that's only because when you construct a string from a const char*
without providing a size the string class does the reasonable thing and
assumes that you passed it a pointer to a C-style null terminated string.
Here's the right way to construct a string with embedded nulls:
#include <string>
#include <iostream>
#include <cctype>
int main() {
std::string s("abc\0\def\0ghi", 11);
for(std::string::const_iterator i=s.begin(), e=s.end(); i!=e; ++i) {
std::cout << static_cast<int>(*i) << ' ';
std::cout << (std::isprint(*i) ? *i : ' ') << '\n';
Yes. But, it's legal. std::string is not needed that its sequence must
be a "string". std::string can store all kinds of char objects.
S Kim
Quite incorrect for std::string.
> string s("abc\0def\0ghi") is equal to string("abc");
This is true. Obviously, you don't understand the difference
between a null-terminated array of characters and a std::string.
You can construct the latter from the former, but the latter is
not bound by the limitations of the former.
char array[] = "abc\0def\0ghi";
std::string s1(array, array + sizeof(array) - 1);
std::string s2("abc");
Then s1 is not equal to s2.
> If you are using Windows, you can use the BSTR type.
> It supports embedded nulls. It is a unicode
> length-prefixed "string".
Irrelvant in a universal C++ newsgroup,
and unnecessary besides.
While it is true that std::string("abc\0def\0ghi") is equal to
std::string("abc"), that is not due to std::string but due to
the common interpretation of how a string is represented when
saved by a type of char *.
Strings that are represented as char * use the null character (\0)
to terminate them. When a std::string intialized itself from that,
it must abide by that.
But you can easily initialize a std::string in other ways as well.
Consider the following:
char rawstr[] = "abc\0def\0ghi";
// -1 to ignore the NULL automatically tacked on by the compiler
size_t rawstr_len = sizeof(rawstr) - 1;
std::string str(rawstr, rawstr_len);
str now has a null character in it.
moo,
samuel
Wrong. A string is a specialization of the basic_string
class template for the
char type, by default using the standard char traits and
allocator. It can
hold any value of type char. You gave the behavior of one
of the
converting constructors of that class. But it is perfectly
legitimate and very
easy to get NULs into the string.
> If you are using Windows, you can use the BSTR type. It
supports embedded
> nulls. It is a unicode length-prefixed "string".
A BSTR has several problems including nonportability and and
even heavier
implementation than basic_string.
Mike Terrazas
> No, you can't put nulls in a string.
Sure you can.
> A string is an sequence of characters,
> which is terminated by a null.
No, that is a C-string not a C++ string.
> string s("abc\0def\0ghi") is equal to string("abc");
You are initializing a C++ string from a C string which
can not see the nul characters. If you know C++, it is
no problem. It might also require a real C++ compiler.
string bad("abc\0def\0ghi"), good("abc\0def\0ghi", 11);
Your bad string lost everything after the first nul while
my good string has everything.
John
kurt krueckeberg schrieb:
> No, you can't put nulls in a string. A string is an sequence of
characters,
> which is terminated by a null.
> string s("abc\0def\0ghi") is equal to string("abc");
This answer is only partially correct.
1) If you use the basic_string constructor basic_string(const charT* s,
const
Allocator& a = Allocator()); (as performed above), it will use the
traits:length() function which for std::string results in the
determination of
the first char() character. This supports Kurt's statement.
2) But you can also use either
basic_string(const charT* s, size_type n, const Allocator& a =
Allocator());
or the generalized c'tor template:
template<class InputIterator>
basic_string(InputIterator begin, InputIterator end, const Allocator& a
=
Allocator());
The first two forms require, that const charT* s MUST NOT be NULL, but
the
generalized form can handle this (provided that both begin AND end are
== NULL)
Greetings from Bremen,
Daniel Spangenberg
> A string is an sequence of characters,
> which is terminated by a null.
> string s("abc\0def\0ghi") is equal to string("abc");
That's right - because the constructor "std::string::string(char
const*)"
treats its argument as a pointer to a classical null-terminated C-style
string. However, there a other constructors, as
"std::string::string(char const* ptr, size_type count)" (size_type being
an
implementation-defined unsigned integer type) that allow you to
construct
a std::string from a char array with embedded nulls:
std::string s("abc\0def\0ghi", 11);
It is also possible to use the templated constructor taking a pair of
input iterators (instantiated with 'char const*' as iterators):
char const foo[] = "abc\0def\0ghi";
std::string s(foo, foo+11);
Similarly, many of the std::string member functions like 'assign',
'append', 'compare', 'insert', replace', 'find.*' etc. are overloaded
to accept both null-terminated char arrays, and char arrays containing
embedded nulls (giving a 'count' parameter), as well as input iterator
pairs.
Care must also be taken if you need to copy the data back form the
std::string
into a C-style char array:
char* pc = new char[s.size() + 1];
//strcpy(pc, s.c_str()); // Wrong: Will stop copying at the first
embedded '\0'!
memcpy(pc, s.data(), s.size()); // OK, copies everything.
pc[s.size()] = '\0'; // Append last terminating '\0'
Apart from when interfacing with C-style strings, there is nothing
special
with embedded '\0' in std::string.
Falk
"kurt krueckeberg" <res0...@verizon.net> wrote in message
news:FdT4a.14026$_k4....@nwrddc03.gnilink.net...
> No, you can't put nulls in a string. A string is an sequence
of characters,
> which is terminated by a null.
> string s("abc\0def\0ghi") is equal to string("abc");
This is only because of the way this constructor works. It
expects the C-like strings, which are in fact zero-terminated.
This does not mean, that entire std::string has this property:
char buf[] = {'a', 'b', 'c', 0, 'd', 'e', 'f', 0, 'g', 'h', 'i'};
string s(&buf[0], &buf[0] + sizeof(buf));
now you get the whole string with zeros inside.
The similar confusion can be found with c_str() member - its
meaning is also defined in terms of C-like strings, so it is not
the good way to extract values with embedded zeros:
cout << s.size() << ' ' << s.c_str();
prints:
11 abc
You can also try this:
cout << boolalpha << (s == "abc");
prints:
false
--
Maciej Sobczak
http://www.maciejsobczak.com/
Distributed programming lib for C, C++, Python & Tcl:
http://www.maciejsobczak.com/prog/yami/
> > I'm using some libraries which use arrays of characters to store
> > lists of strings woth \0 as a delimiter ( \0\0 indicates end of list
> > ).
> > I would like to pass such string lists around as std::string. I'm
> > wondering if it is legal to put nulls in std::string.
> Yep, it's perfectly valid for NUL characters to be in a std::string.
It's perfectly legal, but be aware that at least one major library, the
one delivered with VC++ 5.0 and 6.0, had problems with this. If you
have to port to one of these compilers, be sure and get an upgrade of
the library for it.
--
James Kanze mailto:jka...@caicheuvreux.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Yes it is, the only danger is that you'll get odd results if you attempt
to use the contents of that string as a C null terminated string - you
can end up with:
str.length() != strlen( str.c_str() )
So long as you're sticking with std::string there isn't a problem,
trying to convert to or from C strings is where you run into trouble
since they have different rules.
Bob