2015-05-16 2 views
11

Есть два string переменные, m и n:C++: О нулевых символов

#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 символов. Почему это так?

+0

Вам не нужен явный нулевой символ, поскольку он уже существует –

+0

Прошу прощения за дублированный вопрос. Отныне я пытаюсь решить свой вопрос, ища более внимательно. – carrot031

ответ

10

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

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

Во втором примере вы добавляете символ к существующему объекту std::string длиной 7. Это увеличивает длину до 8. Если вы должны были перебирать элементы строки, вы могли бы увидеть, что этот 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 «s итераторой конструктора :

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); 
+0

Большое спасибо! Теперь я понимаю, почему это происходит. Есть ли способ инициализировать std :: string со строкой, содержащей нулевые символы? – carrot031

+0

@ carrot031 Вы можете сказать, например, 'string s {'a', 'b', '\ 0', 'd', 'e', ​​'\ 0', 'g'};' – juanchopanza

+0

Лучше использовать конструктор итератора, поскольку указатели являются действительными итераторами с произвольным доступом. – Puppy

8

В 1-ом образце

string m = "0100700\0"; 

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

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


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

Для инициализации строки из буквальным, содержащий '\0' символы Cain либо указать количество явно

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

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

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

Большое спасибо за ваш быстрый ответ! Есть ли способ умной инициализации std :: string со строкой, содержащей нулевые символы? – carrot031

+0

Он выглядит более читаемым! Я буду использовать это. Я пытаюсь создать библиотеку C++ для создания архивов tar. – carrot031

Смежные вопросы