Sebastian Hoffmann
Sebastian Hoffmann

Reputation: 11502

std::string without null-character

Is a std::string without a null-character in the end valid and can it be acquired like this?:

std::string str = "Hello World";
str.resize(str.size() - 1);

For those who are curious:

I have a 3rd party function taking a string and iterating over the chars (using iterators). Unfortunately the function is buggy (as its a dev-version) and cannot deal with null-characters. I dont have another signature to chose from, I cant modify the function (as I said, 3rd party and we dont want to fork) and at the same time I dont want to reinvent the wheel. As far as I can tell, the function should work as desired without the null-character so I want atleast to give it a try.

The iteration takes place like this:

bool nextChar(CharIntType& c)
{
    if (_it == _end) return false;
    c = *_it;
    ++_it;
    return true;
}

where _it is initialized to std::string::begin() and _end to std::string::end()

Upvotes: 1

Views: 7231

Answers (3)

Khoa Tran
Khoa Tran

Reputation: 63

This is a very late answer but I just post it so that anyone who comes later can use it for their reference. If you write a null terminated string into the string.data() array, it will terminate the string and would not let you to continue concatenate the string if you need to. The way to solve it is already answer in the question.

  str.resize(str.size() - 1); 

This would solve the problem, I have tested out in my code.

Upvotes: -1

kfsone
kfsone

Reputation: 24269

Until C++11, std::string was not required to include a trailing nul until you called c_str().

http://en.cppreference.com/w/cpp/string/basic_string/data

std::string::data()

Returns pointer to the underlying array serving as character storage. The pointer is such that the range [data(); data() + size()) is valid and the values in it correspond to the values stored in the string.

The returned array is not required to be null-terminated. If empty() returns true, the pointer is a non-null pointer that should not be dereferenced. (until c++11)

The returned array is null-terminated, that is, data() and c_str() perform the same function. If empty() returns true, the pointer points to a single null character. (since c++11)

From this we can confirm that std::string::size does not include any nul terminator, and that std::string::begin() and std::string::end() describe the ranges you are actually looking for.

We can also determine this by the simple fact that std::string::back() doesn't return a nul character.

#include <iostream>
#include <string>

int main() {
    std::string s("hello, world");
    std::cout << "s.front = " << s.front() << " s.back = " << s.back() << '\n';
    return 0;
}

http://ideone.com/nUX0AB

Upvotes: 7

theDarse
theDarse

Reputation: 737

While it is possible to have non null terminated strings I would not recommend it, strings are null terminated for a good reason, i would actually recommend in this instance that you either go ahead and write the function properly or get in touch with the third party and have them fix it.

To answer your questions yes a std::string is valid if it is not null terminated, to achieve this you can use the overload of string copy with a maximum length loaded, once again i do not recommend this.

See this page for more information: http://c2.com/cgi/wiki?NonNullTerminatedString

Upvotes: 0

Related Questions