2014-11-05 2 views
1

Я надеялся, что я получу еще одно объяснение. Мне сказали, что мне нужно явно добавить \0 в конец строки. По-видимому, это для строкового класса C++ и что на самом деле это массив символов, который, по-видимому, анализируется под капотом. Мне сказали, что мы должны использовать \ 0 для того, чтобы сказать, где конец строки, как показано ниже:Почему строка C++ нуждается в 0?

int main() 
{ 
    char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; 
    cout << str << endl; 

    return 0; 
} 

Однако, если у меня есть пользовательский ввод их имя, например, я не что C++ автоматически использует \ 0 для завершения строки. Поэтому аргумент, что \ 0 должен быть там, чтобы знать, где заканчивается строка, не имеет смысла. Почему мы не используем функцию .length() для учета длины строки?

Я написал следующую программу, чтобы проиллюстрировать, что длина ввода может быть найдена из функции .length().

int main() 
{ 
    string firstName; 

    cout << "Enter your first name: "; 
    cin >> firstName; 
    cout << "First Name = " << firstName << endl; 
    cout << "String Length = " << firstName.length() << endl; 

    return 0; 
} 

Итак, если пользователь вводит имя «Том». Тогда результат будет следующий:

First Name = Tom 
String Length = 3 

Я обратил на это внимание моего профессора, а также эта статья http://www.cplusplus.com/reference/string/string/length/ , и мне сказали, что именно поэтому я в колледже, потому что это не может быть сделано таким образом. Может ли кто-нибудь предложить какое-либо понимание, так как я не понимаю, чего не хватает?

+2

Вы вводите в заблуждение 'char []' и 'quoted строковые литералы" и класс 'string' willy-nilly здесь. Просьба уточнить ваш фактический вопрос. Цель цикла полностью ускользает от меня, а также то, что означает ваш вывод. – EJP

+0

Вы путаете std :: string со строками C. 'Почему мы не используем функцию .length() для учета длины строки.' Как вы думаете, std :: string: length знает длину строки? – Falmarri

ответ

2

«C-строка» была переведена на C++ с языка C. Язык C не имел типа string. Строки в C были представлены как массив из char, а строка была прервана байт NUL (\0). В простом литерале строки в C++ все еще есть семантика.

Тип C++ string поддерживает длину внутри объекта, как вы говорите, поэтому в string NUL не требуется. Чтобы получить «C-строку» от string, вы можете использовать метод c_str() на string. Это полезно, если вам нужно передать содержимое C++ string функции, которая понимает только NUL-конец.

std::string s("a string"); // s is initialized, 
          // the length is computed when \0 is encountered. 
assert(s.size() == sizeof("a string")-1); 
          // sizeof string literal includes the \0 
assert(s.c_str()[s.size()] == '\0'); 
          // c_str() includes the \0 

В вашей первой программе вы инициализируете массив символов с помощью списка инициализаторов. Инициализации эквивалентно следующему:

char str[6] = "Hello"; 

Этот стиль инициализации массива char специальная надбавка, что C++ обеспечивает, так как это синтаксис принят С.

В вашей второй программе, вы получив имя от стандартного ввода. Когда C++ сканирует вход, чтобы заполнить аргумент string, он по существу сканирует байты по байтам, пока не встретит разделитель (символы пробелов, по умолчанию). Он может или не может вставить в конце нулевой байт.

0

Вы ничего не пропустите. Нулевой ограничитель используется на символьных массивах для указания конца. Однако класс string заботится обо всем этом для вас. Атрибут length - это вполне приемлемый способ сделать это, поскольку вы используете строки.

Однако, если вы используете массив символов, то да, вам нужно будет проверить, находится ли вы на нулевом терминаторе, поскольку вы, возможно, не знаете длину своей строки.

Следующие вопросы не останутся без ответа.

int length = 2; 
char str[] = "AB"; 

Однако попробуйте следующее, и вы увидите некоторые проблемы.

int length = 5; 
char str[length + 1] = "ABCDE"; // +1 makes room for automatic \0 

char str2[length + 1] = "ABC"; 

Попробуйте второй пропущено, используя ваше для метода петли зная длину, и первые один даст вам ABCDE, но второй один даст вам «ABC», а затем один нездоровой характер. Это только одно, потому что в вашем массиве будет [A][B][C][\0][JUNK]. Увеличьте длину, и вы увидите больше барахла.

2

jxh правильный. C-строки - это char-массивы, а массивы не имеют атрибута длины, который вы можете запросить (хотя вы можете получить размер массива с помощью sizeof (...) в некоторых случаях). Поэтому, когда вы обрабатываете c-подобные строки, вы должны прервать их с помощью \ 0 или \ n.

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