Для обычных строк C нулевой символ '\0'
означает конец данных.Может ли строка std :: содержать встроенные нули?
Как насчет std::string
, могу ли я иметь строку со встроенными нулевыми символами?
Для обычных строк C нулевой символ '\0'
означает конец данных.Может ли строка std :: содержать встроенные нули?
Как насчет std::string
, могу ли я иметь строку со встроенными нулевыми символами?
Да вы можете иметь встроенные нули в своем std::string
.
Пример:
std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);
Примечание: std::string
«s c_str()
член всегда будет добавлять нулевой символ в возвращаемом буфере полукокса; Однако std::string
член data()
может добавлять или не добавлять нулевой символ в возвращаемый буфер символов.
Будьте осторожны оператора + =
Одна вещь, чтобы смотреть на это, чтобы не использовать 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<char> buf;
buf.resize(1024);
char *p = &buf.front();
Это, вероятно, более распространенный, так как std::string
«s data()
и c_str()
членов возвращают константные указатели, так что память не изменяемая. с & buf.front() вы можете напрямую изменять содержимое буфера.
В C++ 9x '& s.front()' также может быть изменен и гарантированно указывать на непрерывный буфер. Хотя в C++ 03 не было такой гарантии, не существует известных реализаций C++, для которых она не выполнялась на практике (отчасти это было добавлено в C++ 0x так быстро). –
Обратите внимание, что с C++ 11 '.c_str()' и '.data' являются синонимами. В частности, это означает, что строка, возвращаемая '.ata ', должна иметь добавленный нулевой ограничитель. – nneonneo
@PavelMinaev: Я предполагаю, что «C++ 9x» был опечаткой для «C++ 0x» (который стал C++ 11 через некоторое время после того, как вы отправили свой комментарий). –
Да, это действительно.
Вы можете иметь нулевой символ в середине строки.
Однако, если вы используете зЬй :: строку с нулевым символом в середине с асами строкой функции ваш в неопределенном поведении города - и никто не хочет быть там !!!:
int n = strlen(strWithNullInMiddle.c_str()); // Boom!!!
'strlen' будет просто вернуть число символов до первого значения null. Это может быть непредвиденное поведение, но это не является неопределенным. –
Да. Строка std :: это всего лишь vector<char>
с преимуществами.
Однако, будьте осторожны о прохождении такого зверя к чему-то, что вызывает .c_str()
и останавливается на 0.
Первое не так, как я недавно узнал. Смена вектора сохраняет итераторы и ссылки на содержимое, строка не обязательно. http://stackoverflow.com/questions/25201758/stringswap-complexity-under-visual-studio – Notinlist
@Notinlist: У него другое имя! О, ужас –
Вы можете, но зачем вы хотите? Вложение NUL в std :: string просто вызывает проблемы, потому что функции, которым вы передаете std :: string, могут очень хорошо использовать его член c_str(), и большинство из них предположит, что первый NUL указывает конец строки. Следовательно, это не очень хорошая идея. Также обратите внимание, что в UTF-8 только «\ 0» приведет к 0, поэтому даже для целей i18n нет никаких оснований для внедрения NUL.
Спасибо за объяснение, почему * не *, чтобы это сделать. – Snoopy
Нет, это глупо. Msgstr "Не использовать весь диапазон функций' std :: string', потому что вы _might_ передаете результат 'c_str()' в функции C-строки без передачи длины ", действительно? Ну, если ты этого не сделаешь, с тобой все будет хорошо ... –
См. [Std :: string-эквивалент для данных с NULL-символами?] (Http://stackoverflow.com/questions/1534335/stdstring-equivalent-for-data-with-null-characters) –