Для обычных строк C нулевой символ '\0'
означает конец данных.
Как насчет std::string
, могу ли я иметь строку со встроенными нулевыми символами?
Для обычных строк C нулевой символ '\0'
означает конец данных.
Как насчет std::string
, могу ли я иметь строку со встроенными нулевыми символами?
Да, вы можете иметь встроенные нули в свой std::string
.
Пример:
std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);
Примечание. Член c_str()
std::string
всегда будет добавлять нулевой символ к возвращаемому буферу char; Однако элемент data()
std::string
может добавлять или не добавлять нулевой символ к возвращаемому буферу char.
Осторожно с оператором +=
Одна вещь, на которую следует обратить внимание, это не использовать operator+=
с char*
на правой стороне. Он будет складываться только до нулевого символа.
Например:
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();
Это, вероятно, более распространено, поскольку члены data()
и c_str()
std::string
возвращают константные указатели, поэтому память нельзя изменить. с помощью &buf.front() вы можете напрямую изменять содержимое буфера.
&s.front()
также изменяемо и гарантированно указывает на непрерывный буфер. Хотя в C++03 такой гарантии не было, нет известных реализаций C++, для которых она не выполнялась бы на практике (отчасти поэтому она так быстро была добавлена в C++0x).
- person Pavel Minaev; 23.07.2010
.c_str()
и .data
являются синонимами. В частности, это означает, что к строке, возвращаемой .data
, должен быть добавлен завершающий нуль.
- person nneonneo; 07.02.2013
s.append("\0world", 6);
лучше, чем s += std::string("\0world", 6);
- person n.caillou; 11.12.2017
да. std::string — это просто vector<char>
с преимуществами.
Однако будьте осторожны с передачей такого зверя чему-то, что вызывает .c_str()
и останавливается на 0.
Вы можете, но зачем вам это? Встраивание NUL в std::string просто напрашивается на неприятности, потому что функции, которым вы передаете std::string, вполне могут использовать его член c_str(), и большинство предположит, что первый NUL указывает на конец строки. Следовательно, это не очень хорошая идея. Также обратите внимание, что в UTF-8 только '\0' приведет к 0, поэтому даже для целей i18n нет никаких оснований для встраивания NUL.
std::string
, потому что вы можете передать результат c_str()
функциям C-строки без передачи длины, правда? Ну, если ты никогда этого не сделаешь, все будет в порядке...
- person Lightness Races in Orbit; 21.05.2017
Да, это действительно.
Вы можете иметь нулевой символ в середине строки.
Однако, если вы используете std::string с нулевым символом в середине со строковой функцией c, вы находитесь в городе с неопределенным поведением - и никто не хочет быть там !!!:
int n = strlen( strWithNullInMiddle.c_str() ); // Boom!!!
strlen
просто вернет количество символов до первого нуля. Это может быть непредвиденным поведением, но оно не является неопределенным.
- person Matthew Flaschen; 17.05.2010