Особенностью потока ввода cin (а точнее – использование операции >>) является то, что он воспринимает пробельные символы в качестве границ вводимых значений. Поэтому если в предыдущем примере пользователь введет с клавиатуры строку "Hello, world!", то в переменную str попадет текст до первого пробела, т.е. – строка "Hello,". Чтобы избежать такой проблемы, можно использовать функцию gets, которая считывает с клавиатуры строку до тех пор, пока пользователь не нажмет «Ввод».
Пример использования функции gets:
#include <iostream>
void main()
{
char str[20];
gets(str);
std::cout << '\n' << str;
}
Имя массива, который нужно заполнить строкой с клавиатуры, указывается в качестве параметра gets. Выводить строки с пробелами можно через оператор cout – он обрабатывает пробелы как обычные символы.
Предостережение! Оба способа ввода строк небезопасны из-за возможности переполнения буфера. Оно возникает, если длина вводимой пользователем строки оказывается больше размера символьного массива. Т.к. ни cin ни gets не контролирует длину строки, то «лишние» символы все равно будут прочитаны и записаны в память, что приведет к изменению данных за пределами массива.
Переполнение буфера демонстрирует следующий пример.
char cstr[] = "Константная строка";
char str[2];
cout << "Введите строку\n";
cin >> str;
cout << "Ваша строка: " << str << '\n';
cout << "Константная строка: " << cstr << '\n';
Результат работы этого кода:
Введите строку
Ваша строка: 123456
Константная строка: 56
Здесь строка из 7 символов (включая нулевой байт в конце) была записана в массив из 2х символов. При этом программа перезаписала данные в памяти, которые не должна была изменять, а именно – значение, хранящееся в строке cstr. Как видно из вывода программы, по адресу cstr теперь находится «окончание» строки str – символы 5, 6 и нулевой байт.
Для того чтобы исключить ошибки переполнения буфера, надо постоянно контролировать длину считываемых срок. Это можно сделать с помощью функций fgets, или get_s которые позволяют ограничить длину считываемой строки указанным значением.