2 :
int main()
{
char SayHello[] = {'H', 'e', *1', '1', 'o', ' ',
|
cout
|
«
|
SayHello
|
«
|
'W',
|
'o',
|
'r', 11 1,
|
'd',
|
6
|
endl;
|
sizeof(SayHello) « endl;
|
7
|
cout
|
«
|
"Size of
|
array:
|
" «
|
8
|
cout
|
«
|
"Replacing
|
space
|
with
|
null" «
|
endl;
|
9
|
SayHello[5] = '\0';
cout « SayHello « endl;
12 cout « "Size of array: " « sizeof(SayHello) « endl;
13
return 0;
}
Результат
Hello World
Size of array: 12
Replacing space with null
Hello
Size of array: 12
Анализ
Код строки 10 заменяет пробел в строке H e llo W orld нулевым символом. Теперь у массива есть два нулевых завершающих символа, но используется первый, что и создает эффект. Когда пробел заменяется нулевым символом, отображаемая строка усекается до части H e llo . Метод s i z e o f () в строках 7 и 12 указывает, что размер массива не изменил ся, несмотря на изменение отображаемых данных.
84 ЗАНЯТИЕ 4. Массивы и строки
ВНИМАНИЕ!
|
Если при объявлении и инициализации символьного массива в строке 5 ли
|
|
|
стинга 4.5 вы забываете добавить символ ' \ 0 ', то после части H ello World
|
|
вывод будет содержать случайный набор символов. Дело в том, что оператор
|
|
s td : :c o u t не остановится на выводе массива, он будет продолжать вывод,
|
|
пока не достигнет нулевого символа, даже если для этого придется перейти
|
|
границы массива.
|
|
Эта ошибка может нарушить вашу программу, а в некоторых случаях поставить
|
|
под угрозу стабильность системы.
|
Строки в стиле С чреваты опасностью. Листинг 4.6 демонстрирует риски, связанные с их применением.
ЛИСТИНГ 4,6. Риск использования строк в стиле С и пользовательского ввода____________
#include
using namespace std;
2 :
int main()
{
5: cout « "Enter a word NOT longer than 20 characters:" « endl;
:
7: char Userlnput [21] = {'\0 '};
cin >> Userlnput;
10: cout « "Length of your input was: " « strlen (Userlnput)
endl;
1 1 :
return 0;
}
Результат
Enter a word NOT longer than 20 characters:
Don'tUseThisProgram
Length of your input was: 19
Анализ
Опасность видна в выводе. Программа просит пользователя не вводить больше двад цати символов. Причина в том, что объявленный в строке 7 символьный буфер, предна значенный для хранения пользовательского ввода, имеет фиксированную статическую длину в 21 символ. Поскольку последний символ в строке должен быть нулевым ' \ 0 ', максимальная длина текста, хранимого буфером, ограничивается двадцатью символами. Обратите внимание на применение оператора s t r l e n в строке 10 для вычисления дли ны строки. Он перебирает символьный буфер и подсчитывает количество символов, пока не достигает нулевого, который означает конец строки. Этот символ был вставлен в ко нец введенных пользователем данных оператором c in . Подобное поведение оператора s t r l e n делает это опасным, поскольку он может легко пересечь границы символьного массива, если пользователь введет текст длиннее упомянутого предела. Чтобы узнать, как
Строки C++: использование типа std::string
|
85
|
реализовать проверку, гарантирующую, что запись в массив не выйдет за его пределы, об ратитесь к листингу 6.2 занятия 6, “Ветвление процесса выполнения программ”.
Строки C++: использование
типа s td :: string
Стандартная строка C++ — самый эффективный способ работы и с текстовым вводом, и при манипуляции строками, например, при их конкатенации.
Приложения, написанные на языке С (или на языке C++ программистами с большим опытом в языке С), зачастую используют в своем коде функции копи рования строк, такие как strcpy, функции конкатенации, такие как street, и определения длины строк, такие как strlen.
Эти функции используют строки в стиле С и потому опасны, так как ищут завер шающий нулевой символ и могут преодолеть границы символьного массива, если программист не гарантировал наличие завершающего нулевого символа.
Язык C++ предоставляет мощное и в то же время безопасное средство манипулирова ния строками — класс s t d : : s t r i n g , представленный в листинге 4.7. Класс s t d : : s t r i n g реализован не на статическом массиве типа c h a r неизменного размера, как строки в стиле С, и допускает увеличение размера, когда в нем необходимо сохранить больше данных.
ЛИСТИНГ 4-7- Использование типа std::string для инициализации и хранения пользовательского ввода, а также копирование, конкатенация и определение длины строки
Do'stlaringiz bilan baham: |