- •Буферизація
- •Потоки і буфери
- •Стандартні об'єкти введення-виводу
- •Лістинг 3. Введення рядка значень
- •Результат:
- •Введення рядків із стандартного пристрою введення
- •Результат:
- •Використання функції cout.Width()
- •Результат:
- •Лістинг 15. Вывод данных с помощью фцнкции printf()
- •Результат:
- •Лістинг 16. Відкриття файлу для читання і запису
- •Результат:
- •Налаштування відкриття файлу об'єктом ofstream
- •Лістинг 17. Додавання даних в кінець файлу
- •Результат:
- •Двійкові і текстові файли
- •Лістинг 18. Запис класу у файл
- •Результат:
- •Установка параметрів введення-виводу за допомогою коммандной рядка
- •Лістинг 20. Використання аргументів командного рядка
- •Результат:
- •Питання і відповіді
Введення рядків із стандартного пристрою введення
Для заповнення масиву символів можна використовувати як оператора введення (>>), так і методи get() і getline().
Ще один варіант переобтяженої функції get() приймає три параметри. Перший параметр — це покажчик на масив символів, другий вказує максимальне число символів в рядку з врахуванням кінцевого нульового символу, що додається автоматично, і третій задає роздільник рядків.
Якщо для другого параметра встановлено значення 20, функція get() введе 19 символів і обірве введення рядка, на який вказував перший параметр, після чого додасть кінцевий нульовий символ. Третій параметр за умовчанням встановлюється як символ розриву рядка ( \n ). Якщо цей символ зустрінеться раніше, ніж буде введений останній допустимий символ рядка, функція вставить в цьому місці кінцевий нульовий символ, але символ розриву рядка при цьому залишиться в буфері і буде лічений черговою функцією введення.
Реалізація цього методу введення показана в лістингу 6.
Лістинг 6. Використання функції get() для заповнення масиву символів
1: // Лістинг 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(), як показано в лістингу 7.
Лістинг 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() показано в лістингу 8.
Лістинг 8. Використання функції ignore()
1: // Лістинг 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: }