1

So I've implemented the Longest Common Subsequence algorithm for the Introduction to Algorithms book (CLRS) in C++, and it works fine, kinda. When I do something like this:

./lcs abc bc > OUTPUT

When I open the OUTPUT file in vim, I see this:

2 bc^@

Which is correct, sans that weird ^@ symbol. I did some Googling and this appears to be some sort of NULL character?

I've never run into this problem before.. anyone know how to get rid of it?

Thanks! -kstruct

EDIT Here's the code that does the printing:

cout << lcsLength << " ";
    if (lcsLength > 0) cout << lcsString;

return 0;

Where lcsString is a std::string. Not sure if that helps...

adelbertc
  • 7,270
  • 11
  • 47
  • 70
  • 1
    post the line of code that outputs "2 bc" – SirPentor May 23 '12 at 04:14
  • I wonder changing that to `cout << lcsString << endl` would help. – SirPentor May 23 '12 at 04:25
  • 1
    We would need to see what characters are being added to your string. – Vaughn Cato May 23 '12 at 04:30
  • 1
    Your string contains a literal ASCII NUL in it (note that `std::string`s are allowed to contained embedded NULs). If you run `for(int i = 0; i < lcsString.size(); i++) cout << (int)lcsString[i] << ' ';` you'll see something like `50 32 98 99 0`. – Adam Rosenfield May 23 '12 at 04:34
  • Hm, I seem to have been able to fix it by doing `cout << lcsLength.c_str()` instead. In terms of the last character being `NUL`, is it possible? It doesn't seem to be for me, the recursive print LCS algorithm just prints out the `i`th index of one of the input strings once it meets some certain conditions... – adelbertc May 23 '12 at 04:37
  • 1
    If I recall correctly, c_str() returns a `NULL` terminated string, which is probably removing, or replacing the `NUL` in the `string` which `cout` handles, not printing the `NUL` character you are seeing. – Drise May 23 '12 at 04:57
  • Yeah, it's a temporary workaround the problem, but I'd still like to solve the problem. Need to dig through my code to see what could cause my string to accumulate a `NUL` in it... – adelbertc May 23 '12 at 04:58
  • 1
    `c_str()` is returning the byte sequence `'2' ' ' 'b' 'c' NUL NUL` and then the `operator<<` stops printing when it reaches the first of those NULs. The `operator<<` for C strings behaves differently than the `operator<<` for `std::string` in this regard. – zwol May 23 '12 at 05:07

2 Answers2

4

That's NUL (which is a character value, and is defined to be all-bits-zero), not NULL (which is a pointer, almost always also all-bits-zero, but not required to be).

We're gonna need to see your code to know for sure, but the most likely cause of this is that you printed one more byte of a C-string (which always has NUL as its very last byte) than you should have.

zwol
  • 135,547
  • 38
  • 252
  • 361
  • Hm, but I'm printing it with a `std::string`.. I've attached a small code snippet above, let me know what else you may need. – adelbertc May 23 '12 at 04:19
4

You've shown the code that outputs lcsString, but unlike a C style string, a std::string type can contain null characters since the length is maintained separately from the string data itself.

Try adding the following to dump the contents of the string:

cout << "length of lcsString: " << lcsString.length() << endl;
cout << '"' << lcsString << '"' << endl;
for (int i = 0; i < lcsString.length(); ++i) {
    cout << hex <<  int(lcsString[i]) << " ";
}
cout << endl;

I'll bet you will see:

length of lcsString: 3
"bc "
62 63 0 

Then you'll need to find out what you're doing to create (or modify) lcsString such that it contains a null character at the end.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760