Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > <string> class with support of Null-Bytes?

Reply
Thread Tools

<string> class with support of Null-Bytes?

 
 
Karl Ebener
Guest
Posts: n/a
 
      12-14-2004
Hi!

I asked a similar question before but then changed everything to using
char-Arrays instead of the string class, but I would rather not do this
again.

So, does anyone know of a string-Class similar to the STL-<string> that
supports null-bytes?

I tried with standard <string> but this definitely does not support
them...

Tnx
Karl
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      12-14-2004
* Karl Ebener:
>
> I asked a similar question before but then changed everything to using
> char-Arrays instead of the string class, but I would rather not do this
> again.
>
> So, does anyone know of a string-Class similar to the STL-<string> that
> supports null-bytes?
>
> I tried with standard <string> but this definitely does not support
> them...


Depends what you mean by "support", but with usual definitions that's
not correct.

Perhaps post a simple program that shows what you mean by "not support"?

Then we can see whether the problem is in the code or with std::string,
and give better suggestions on how to proceeed.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
 
 
 
Karl Ebener
Guest
Posts: n/a
 
      12-14-2004
Little change:

> I tried with standard <string> but this definitely does not support
> them...


-> I tried using length()-method which stops at null-bytes and c_str()
of course extracts only part till null-byte.
Have I only not seen any possibility to extract the content as char* ?

Tnx
Karl
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      12-14-2004
* Karl Ebener:
> Little change:
>
> > I tried with standard <string> but this definitely does not support
> > them...

>
> -> I tried using length()-method which stops at null-bytes


It doesn't.


> and c_str() of course extracts only part till null-byte.


It doesn't, see 21.3.6/1.


> Have I only not seen any possibility to extract the content as char* ?


Post some code.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Karl Ebener
Guest
Posts: n/a
 
      12-14-2004
Alf P. Steinbach schrieb:
> Depends what you mean by "support", but with usual definitions that's
> not correct.
>
> Perhaps post a simple program that shows what you mean by "not support"?
>
> Then we can see whether the problem is in the code or with std::string,
> and give better suggestions on how to proceeed.
>

Okay, this is my test program.
What I want to do finally, is read a complete (binary) file into a
string and then send this via using socket to/from server.
I am using socket-routines that use strings because it is much easier
this way and I would love to leave it at that and not recode everything...

Tnx
Karl

#include <string>
#include <iostream>

using namespace std;

int main()
{
string abc = "abc\0abc\0"; // string contains Null-bytes
cout << abc << ":" << abc.length() << endl; // output is: 3
FILE* fp;

fp = fopen("ABC", "w");
fwrite(abc.c_str(), 8, 1, fp); // file will contain: "abc" and Garbage
fclose(fp);
}
 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      12-14-2004
Karl Ebener wrote:

> Alf P. Steinbach schrieb:
>> Depends what you mean by "support", but with usual definitions that's
>> not correct.
>>
>> Perhaps post a simple program that shows what you mean by "not support"?
>>
>> Then we can see whether the problem is in the code or with std::string,
>> and give better suggestions on how to proceeed.
>>

> Okay, this is my test program.
> What I want to do finally, is read a complete (binary) file into a
> string and then send this via using socket to/from server.
> I am using socket-routines that use strings because it is much easier
> this way and I would love to leave it at that and not recode everything...
>
> Tnx
> Karl
>
> #include <string>
> #include <iostream>
>
> using namespace std;
>
> int main()
> {
> string abc = "abc\0abc\0"; // string contains Null-bytes


No. Your literal contains 0-bytes. The conversion constructor from C style
strings to std::string of course has to stop at \0, since that's the value
that marks the end of a C style string. Try:

const char c[] = "abc\0abc\0";

string abc(c, sizeof(c));

This tells the constructor to not stop at \0, but read the specified number
of characters.

> cout << abc << ":" << abc.length() << endl; // output is: 3


That's because only the first 3 characters were actually copied into the
string.

> FILE* fp;
>
> fp = fopen("ABC", "w");
> fwrite(abc.c_str(), 8, 1, fp); // file will contain: "abc" and Garbage


Again, that's because the string only contains the first 3 characters.

> fclose(fp);
> }


 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      12-14-2004
* Karl Ebener:
>
> #include <string>
> #include <iostream>
>
> using namespace std;
>
> int main()
> {
> string abc = "abc\0abc\0"; // string contains Null-bytes
> cout << abc << ":" << abc.length() << endl; // output is: 3
> FILE* fp;
>
> fp = fopen("ABC", "w");
> fwrite(abc.c_str(), 8, 1, fp); // file will contain: "abc" and Garbage
> fclose(fp);
> }


The problem in the abc declaration is that you invoke the constructor
that takes a C string as argument, and by definition that C string ends
at the first nullbyte.

Try


#include <string>
#include <iostream>

#define ELEMCOUNT( array ) (sizeof(array)/sizeof(*array))

int main()
{
static char const abc_data[] = "abc\0abc\0";
std::string abc( abc_data, ELEMCOUNT( abc_data );

std::cout << abc << ":" << abc.length() << std::endl;
}

But you might instead (for efficiency) want to use std::vector<char>.

Also, the file should be opened in binary mode.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Dimitris Kamenopoulos
Guest
Posts: n/a
 
      12-14-2004
Karl Ebener wrote:

> Okay, this is my test program.


My guess is that std::string's functions (including constructors) that take
a C-Style string as an argument, *do* treat it as a C-style (i.e.
null-terminated) string.

Makes sense, doesn't it? You don't want

char s[15] = "sth";
string s1(s);

to allocate 11 extra null characters in s1 for no reason

If, OTOH, you put a '\0' in an std::string, it will not be treated as a
terminating character.

Check out this example to see what I mean:

#include <iostream>
#include <string>

int main(){
std::string s("abc\0abc\0");
std::cout<<s.length()<<std::endl; //prints 3, not 9
std::string s2;
s2.push_back('a');
s2.push_back('\0');
s2.push_back('b');
std::cout<<s2.length()<<std::endl; //prints 3, not 1
}


Note: c_string() will return a const char *, which means that the string
returned will always stop at the first null byte, for any code that cares
about it (e.g. strlen or strcpy). Better use a vector<char> if you want
byte semantics.


 
Reply With Quote
 
Dave O'Hearn
Guest
Posts: n/a
 
      12-14-2004
Karl Ebener wrote:
> fwrite(abc.c_str(), 8, 1, fp); // file will contain: "abc"
> // and Garbage


As a separate issue, data() would be better than c_str() here. c_str()
may expand the string's internal buffer, to make room for an extra null
character past the end. You don't need a null-terminated C-string to
call fwrite, so you can just use data().

--
Dave O'Hearn

 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      12-14-2004
Dimitris Kamenopoulos wrote:

> Karl Ebener wrote:
>
>> Okay, this is my test program.

>
> My guess is that std::string's functions (including constructors) that
> take a C-Style string as an argument, *do* treat it as a C-style (i.e.
> null-terminated) string.
>
> Makes sense, doesn't it? You don't want
>
> char s[15] = "sth";
> string s1(s);
>
> to allocate 11 extra null characters in s1 for no reason


That's not the main point. The constructor takes a pointer, which doesn't
contain any information about the size of the array pointed to. So the \0
is the _only_ way at all to know where a C style string ends.

 
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
Class A contains class B, class B points to class A Joseph Turian C++ 5 12-30-2005 03:24 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
A parameterized class (i.e. template class / class template) is not a class? christopher diggins C++ 16 05-04-2005 12:26 AM
ANN: SCons.0.96 adds Fortran 90/95 support, better Qt support,platform-independent file system actions, improved debugging, lots more Steven Knight Python 0 08-18-2004 03:57 PM
Getting Third Party Component Suppliers to support NUnit and NUnitASP to support test driven development in web pages Nick Zdunic ASP .Net 0 11-05-2003 10:45 AM



Advertisments