операторы — C ++: о нулевых символах

Есть два string переменные, m а также n:

#include <string>

string m = "0100700\0"cout << m.size() << endl; // it prints: 7

string n;
n += "0100700"n += '\0';
cout << n.size() << endl; // it prints: 8

Я предположил, что у обоих было 8 символов, но m было всего 7 символов и n было 8 символов. Почему это так?

11

Решение

Первое, что нужно отметить, это то, что std::string не имеет конструктора, который может определить длину строкового литерала из базового массива. Он имеет конструктор, который принимает const char* и обрабатывает его как строку с нулевым символом в конце. При этом он копирует символы, пока не найдет первый \0,

Это конструктор, используемый в string m = "0100700\0";Именно поэтому в первом случае ваша строка имеет длину 7. Обратите внимание, что нет другого способа получить длину массива char от указателя на его первый элемент.

Во втором примере вы добавляете символ к уже существующему std::string объект длины 7. Это увеличивает длину до 8. Если бы вы перебирали элементы строки, вы бы увидели, что этот восьмой элемент '\0',

for (auto c: n)
if (c == 0) std::cout << "null terminator" << std::endl;

Для того, чтобы инициализировать строку, содержащую '\0' персонажи, у вас есть варианты:

Используйте список инициализации:

std::string s{'a', 'b', '\0', 'd', 'e', '\0', 'g'};

Создайте из другого контейнера или массива, используя std::stringИтератор конструктора:

std::vector<char> v{'a', 'b', '\0', 'd', 'e', '\0', 'g'};
char c[] = {'a', 'b', '\0', 'd', 'e', '\0', 'g'};
const char* ps = "ab\0de\0g";

std::string s0(std::begin(v), std::end(v));
std::string s1(std::begin(c), std::end(c));
std::string s2(ps, ps + 8);
10

Другие решения

В 1-м примере

 string m = "0100700\0";

string переменная состоит из символьного литерала и принимает все символы до первого '\0' персонаж найден.

2-й пример показывает, что вы можете добавить произвольное количество дополнительных '\0' персонажи к std::string и увеличить его размер.


Чтобы ответить на вопрос из вашего комментария:

Инициализировать строку из литерала, содержащего '\0'символы, которые вы можете использовать, либо указывают счет явно

string m("0100700\0",8);

или вы можете использовать конструктор, используя first а также last итератор:

 const char x[] = "0100700\0";
string m(std::begin(x),std::end(x));
8

По вопросам рекламы [email protected]