Может ли std :: string содержать встроенные нули? - PullRequest
36 голосов
/ 17 мая 2010

Для обычных строк C нулевой символ '\0' обозначает конец данных.

Как насчет std::string, можно ли получить строку со встроенными нулевыми символами?

Ответы [ 4 ]

37 голосов
/ 17 мая 2010

Да, вы можете встраивать нули в std::string.

Пример:

std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);

Примечание: std::string элемент c_str() всегда будет добавлять нулевой символ в возвращенный буфер символов; Однако std::string член data() может добавлять или не добавлять нулевой символ в возвращенный буфер символов.

Будьте осторожны с оператором + =

Одна вещь, на которую следует обратить внимание, это не использовать operator+= с char* на RHS. Он будет складываться только до нулевого символа.

Например:

std::string s = "hello";
s += "\0world";
assert(s.length() == 5);

Правильный путь:

std::string s = "hello";
s += std::string("\0world", 6);
assert(s.length() == 11);

Хранение двоичных данных, более распространенных для использования std :: vector

Обычно для хранения произвольных двоичных данных чаще используется std::vector.

std::vector<char> buf;
buf.resize(1024);
char *p = &buf.front();

Это, вероятно, более распространено, поскольку члены std::string data() и c_str() возвращают константные указатели, поэтому память не модифицируется с помощью & buf.front () вы можете напрямую изменять содержимое буфера.

7 голосов
/ 17 мая 2010

Да. Std :: string - это просто vector<char> с преимуществами.

Однако, будьте осторожны, передавая такого зверя чему-то, что вызывает .c_str() и останавливается на 0.

0 голосов
/ 17 мая 2010

Можно, но с чего бы вы этого хотели? Внедрение NUL в std :: string просто вызывает проблемы, потому что функции, которым вы передаете std :: string, вполне могут использовать свой член c_str (), и большинство будет предполагать, что первый NUL указывает конец строки. Следовательно, это не очень хорошая идея. Также обратите внимание, что в UTF-8 только '\ 0' приведет к 0, поэтому даже для целей i18n нет оправдания для встраивания NUL.

0 голосов
/ 17 мая 2010

Да, это действительно.

Вы можете иметь нулевой символ в середине строки.

Однако, если вы используете std :: string с нулевым символом в середине со строкой c функционируй в городе неопределенного поведения - и никто не хочет быть там !!!:

 int n = strlen( strWithNullInMiddle.c_str() ); // Boom!!!
...