Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Листинг 16.6. Использование функции get() для заполнения массива символов
1: // Листинг 16.6. Использование get()c массивом символов 2: #include < iostream.h> 3: 4: int main() 5: { 6: char stringOne[256]; 7: char stringTwo[256]; 8: 9: cout < < " Enter string one: "; 10: cin.get(stringOne, 256); 11: cout < < " stringOne: " < < stringOne < < endl; 12: 13: cout < < " Enter string two: "; 14: cin > > stringTwo; 15: cout < < " StringTwo: " < < stringTwo < < endl; 16: return 0; 17: }
Результат: Enter string one: Now is the time stringOne: Now is the time Enter string two: For all good StringTwo: For
Анализ: В строках 6 и 7 создаются два массива символов. Строка 9 предлагает пользователю ввести строку, после чего в строке 10 вызывается функция cin.get() с тремя параметрами. Первый параметр ссылается на заполняемый массив символов, второй задает максимально возможное количество символов в строке с учетом нулевого концевого символа ('\0'). Третий параметр не установлен, и используется заданный по умолчанию символ разрыва строки. Пользователь вводит строку Now is the time. Вся строка вместе с концевым нулевым символом помещается в массив stringOne. Вторую строку пользователю предлагается ввести в строке 13, однако в этом случае уже используется оператор ввода. Поскольку он считывает строку до первого пробела, во втором случае в буфер заносится строка Все, что, конечно же, неправильно. Один из способов решения этой проблемы заключается в использовании функции getline(), как показано в листинге 16.7. Листинг 1B.7. Использование функции getline() 1: // Листинг 16.7. Использование getline() 2: #include < iostream.h> 3: 4: int main() 5: { 6: char stringOne[256]; 7: char stringTwo[256]; 8: char stringThree[256]; 9: 10: cout < < " Enter string one: "; 11: cin.getline(stringOne, 256); 12: cout < < " stringOne: " < < stringOne < < endl; 13: 14: cout < < " Enter string two: "; 15: cin > > stringTwo; 16: cout < < " stringTwo: " < < stringTwo < < endl; 17: 18: cout < < " Enter string three: "; 19: cin.getline(stringThree, 256); 20: cout < < " stringThree: " < < stringThree < < endl; 21: return 0; 22: }
Результат: Enter string one: one two three stringOne: one two three Enter string two: four five six stringTwo: four Enter string three: stringThree: five six
Анализ: Этот пример требует детального исследования, поскольку возможны некоторые сюрпризы. В строках 6—8 объявляются массивы символов. В строке 10 пользователю предлагается ввести строку текста, которая считывается функцией getline(). Аналогично функции get(), параметры getline() устанавливают буфер ввода и максимальное число символов. Однако, в отличие от get(), функция getline() считывает и удаляет из буфера символ разрыва строки. Как вы помните, функция get() воспринимает символ разрыва строк как разделитель и оставляет его в буфере ввода. В строке 14 пользователю вновь предлагается ввести строку, которая теперь уже считывается оператором ввода. В нашем примере вводится строка four five six, после чего первое слово four присваивается переменной stringTwo. После отображения предложения Enter string three: снова вызывается функция getline(). Так как часть строки five six все еще находится в буфере ввода, она сразу считывается до символа новой строки. Функция getline() завершает свою работу, и строкой 20 выводится значение переменной stringThree. В результате третья строка не вводится в программу, поскольку функция getline() возвращает часть строки, оставшуюся в буфере после операции ввода в строке 15, так как оператор > > считывает строку только до первого пробела и вставляет найденное слово в массив символов. Как вы помните, можно использовать несколько вариантов перегруженной функ- ции-члена get(). В первом варианте она не принимает никаких параметров и возвращает значение полученного символа. Во втором принимается ссылка на односимвольную переменную и возвращается объект istream. В третьей, последней версии в функцию get() устанавливаются массив символов, количество считываемых символов и символ разделения (которым по умолчанию является разрыв строки). Эта версия функции get () возвращает символы в массив либо до тех пор, пока не будет введено максимально возможное количество символов, либо до первого символа разрыва строки. Если функция get() встречает символ разрыва строки, ввод прерывается, а символ разрыва строки остается в буфере ввода. Функция-член getline() также принимает три параметра: буфер ввода, число символов в строке с учетом концевого нулевого символа и символ разделения. Функция getline() действует аналогично описанной выше функции get(), но отличается от последней только тем, что не оставляет в буфере символ разрыва строки. Использование функции cin.ignore()
В некоторых случаях возникает необходимость пропустить часть символов строки от начала до достижения конца строки (EOL) или конца файла (EOF). Именно этому и отвечает функция ignore(). Она принимает два параметра: число пропускаемых символов и символ разделения. Например, вызов функции ignore(80, '\n') приведет к пропуску 80 символов, если ранее не будет найден символ начала новой строки. Последний затем будет удален из буфера, после чего функция ignore() завершит свою работу. Использование функции ignore() показано в листинге 16.8. Листинг 16.8. Использование функции ignore() 1: // Листинг 16.8. Использование ignore() 2: #include < iostream.h> 3: 4: int main() 5: { 6: char string0ne[255]; 7: char stringTwo[255]; 8: 9: cout < < " Enter string one: "; 10: cin.get(stringOne, 255); 11: cout < < " String one: " < < stringOne < < endl; 12: 13: cout < < " Enter string two: "; 14: cin.getline(stringTwo, 255); 15: cout < < " String two: " < < stringTwo < < endl; 16: 17: cout < < " \n\nNow try again...\n"; 18: 19: cin.ignore(255, '\n'); 20: cout < < " Enter string two: "; 21: cin.getline(stringTwo, 255); 22: 23: cout < < " String Two: " < < stringTwo< < endl; 24: 25: cout < < " Enter string one: "; 26: cin.get(stringOne, 255); 27: cout < < " String one: " < < stringOne< < endl; 28: return 0; 29: }
Результат: Enter string one: once upon а time String one: once upon а time Enter string two: String two: Now try again... Enter string one: once upon a time String one: once upon a time Enter string two: there was a String Two: there was a
Анализ: В строках 6 и 7 создаются два массива символов. В строке 9 пользователю предлагается ввести строку. В нашем примере вводится строка once upon а time. Ввод завершается нажатием < Enter>. В строке 10 для считывания этой строки используется функция get(), которая присваивает эту строку переменной stringOne и останавливается на символе начала новой строки, оставляя его в буфере ввода. В строке 13 пользователю еще раз предлагается ввести вторую строку, однако в этот раз функция getline() в строке 14 считывает символ разрыва строки, оставшийся в буфере, и сразу же завершает свою работу. В строке 19 пользователю предлагается ввести первую строку. Однако в этом случае для пропуска символа разрыва строки используется функция ignore() (см. в листинге 16.8 строку 23). Таким образом, при вызове getline() строкой 26 буфер ввода пуст, и пользователь получает возможность ввести следующую строку.
Функции-члены peek() и putback()
Объект cin обладает двумя дополнительными методами, которые могут оказаться весьма полезными. Метод peek()просматривает, но не считывает очередной символ. Метод putback() вставляет символ в поток ввода. Использование этих методов показано в листинге 16.9. Листинг 16.9. Использование функций peek() В putback() 1: // Листинг 16.9. Использование peek() и putback() 2: #include < iostream.h> 3: 4: int main() 5: { 6: char ch; 7: cout < < " enter а phrase: "; 8: while (cin.get(ch)) 9: { 10: if (ch == '! ') 11: cin.putback('$'); 12: else 13: cout < < ch; 14: while (cin.peek() == '#') 15: cin.ignore(1, '#'); 16: } 17: return 0; 18: }
Результат: enter а phrase: Now! is#the! time#for! fun#! Now$isthe$timefor$fun$
Анализ: В строке 6 объявляется символьная переменная ch, а в строке 7 пользователю предлагается ввести строку текста. Назначение этой программы состоит в том, чтобы заменить все встречающиеся во введенной строке восклицательные знаки (!) знаком доллара ($) и удалить все символы (#). Цикл while в теле функции main() программы прокручивается до тех пор, пока не будет возвращен символ конца файла (вводится комбинацией клавиш < Ctrl+C> в Windows или < Ctrl+Z> и < Ctrl+D> в MS DOS и UNIX соответственно). (Не забывайте, что функция cin.get() возвращает 0 в конце файла.) Если текущий символ оказывается восклицательным знаком, он отбрасывается, а в поток ввода функцией putback() возвращается символ $. Если же текущий символ не является восклицательным знаком, он выводится на экран. Если текущий символ оказывается #, то он пропускается функцией ignore(). Указанный подход далеко не самый эффективный способ решения подобных задач (более того, если символ # будет расположен в начале строки, то программа его пропустит). Но наша основная цель состояла в том, чтобы продемонстрировать работу функций putback() и ignore(). Впрочем, их использование достаточно просто и понятно.
Примечание: Методы peek() и putback() обычно используются для синтаксического анализа строк. Необходимость в нем возникает, например, при создании компилятора.
|