Subject: [Dev] null terms for strings

From: "M. Mueller" <[email-masked]>
Date: Tue, 7 May 2002 14:30:32 -0400

Here's a little program that captures a problem I had today.  I have a map 
container, map<string, t_myStruc), that I want to duplicate on another 
machine.  I pack each entry into datagram and send it via sockets to another 
machine where each packet is collected and used to build a copy of the map 
entry by entry.  So, I convert the string key to an array of chars for the 
journey to the other side.  In the process I got confused about the function 
of null terminators on char array strings versus string objects.

To compile: g++ -o test test.cpp

<snip start>
#include <string>
using namespace std;

main()
{
	string a;
	a  = 'a';
	a += ' ';
	a += 's';
	a += 't';
	a += 'r';
	a += 'i';
	a += 'n';
	a += 'g';
	a += '\0';
	string b;
	b  = 'a';
	b += ' ';
	b += 's';
	b += 't';
	b += 'r';
	b += 'i';
	b += 'n';
	b += 'g';

	if (a == b) 
		cout << "a equals b\n";
	else
		cout << "a not equals b\n";

	if (strcmp(a.c_str(), b.c_str()) == 0)
		cout << "a.c_str() equals b.c_str()\n";
	else 
		cout << "a.c_str() not equals b.c_str()\n";
	
}
<snip end>

-- 
Michael Mueller
Signalnetware, Inc.
www.signalnetware.com
919.621.6090

---

From: Tanner Lovelace <[email-masked]>
Date: 07 May 2002 14:55:32 -0400

> of null terminators on char array strings versus string objects.

Well, for one thing, a C++ string may or may not be null terminated.
Officially, it's not specified as to how they are stored internally.
So, when in doubt, assume it's not.

> 		cout << "a.c_str() not equals b.c_str()\n";

Well, I haven't run it, but just looking at it, I'd say the
strings are not the same.  String a has a null character at
the end and string b doesn't.  

In addition, I'd be interested in seeing what the .c_str() 
function returned.  I'd bet it doesn't do any checking for
stuff like this and the c-style strings that get returned
*are* the same (because they *must* have a null at the end)
even though the C++ strings are not.

I would just suggest sending over the output of the .c_str()
function of each string and then using the string constructor
to recreate them on the other side.

Tanner
-- 
Tanner Lovelace | [email-masked] | http://wtl.wayfarer.org/
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
GPG Fingerprint = A66C 8660 924F 5F8C 71DA  BDD0 CE09 4F8E DE76 39D4
GPG Key can be found at http://wtl.wayfarer.org/lovelace.gpg.asc
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
Have we sent the "Don't shoot, we're pathetic" transmission yet? 
                                Commander John Crichton (Farscape)

---

From: Ed Hill <[email-masked]>
Date: 07 May 2002 13:39:02 -0600

> of null terminators on char array strings versus string objects.

Hi Mike,

I tested your snippet and got:

[edhill@eddy ~]$ ./a.out
a not equals b
a.c_str() equals b.c_str()
[edhill@eddy ~]$

which I'm sure is your complaint.

Heres a fix:  How about writing the re-assembly part of your code so
that, by default, it automatically strips any trailing nulls?

Its easy and then you don't have to worry about whether you sent the
string with null termination or not.  Of course, its a lousy idea if
your strings ever need to contain imbedded nulls, but that may not be a
problem...

hth,
Ed

-- 
Edward H. Hill III, PhD    |  Email:       [email-masked], [email-masked]
Post-Doctoral Researcher   |  URLs:        http://www.eh3.com
Division of ESE            |   http://wasser.mines.edu/people/edhill.php
Colorado School of Mines   |  Phone:       303-273-3483
Golden, CO  80401          |  Fax:         303-273-3311
Key fingerprint = 5BDE 4DA1 66BE 4F7B BC17  3A0C 932B 7266 1E76 F123