стандартні потоки

Що стосується файлової системи мови С, то на початку виконання програми автоматично відкриваються три потоки. Це stdin (стандартний потік введення), stdout (стандартний потік виводу) і stderr (стандартний потік помилок). Зазвичай ці потоки направляються до консолі, але в середовищах, які підтримують перенаправлення вводу / виводу, вони можуть бути перенаправлені операційною системою на інший пристрій. (Перенаправлення вводу / виводу підтримується, наприклад, такими операційними системами, як Windows, DOS, UNIX і OS / 2.)

Так як стандартні потоки є покажчиками файлів, то вони можуть використовуватися системою введення / виводу мови С також для виконання операцій введення / виводу на консоль. Наприклад, putchar () може бути визначена таким чином:

Взагалі кажучи, stdin використовується для зчитування з консолі, a stdout і stderr - для запису на консоль.

У ролі покажчиків файлів потоки stdin. stdout і stderr можна застосовувати в будь-який функції, де використовується змінна типу FILE *. Наприклад, для введення рядка з консолі можна написати приблизно такий виклик fgets ().

І дійсно, таке застосування fgets () може виявитися досить корисним. Як вже говорилося в цій книзі, при використанні gets () не виключена можливість, що масив, який використовується для прийому вводяться користувачем символів, буде переповнений. Це можливо тому, що gets () не проводить перевірку на відсутність порушення кордонів. Корисною альтернативою gets () є функція fgets () з аргументом stdin. так як ця функція може обмежувати число Новомосковскемих символів і таким чином не допустити переповнення масиву. Єдина проблема, пов'язана з fgets (). полягає в тому, що вона не видаляє символ нового рядка (в той час як gets () видаляє!), тому його доводиться видаляти "вручну", як показано в наступній програмі:

He забувайте, що stdin. stdout і stderr - це не змінні в звичайному сенсі, і їм не можна присвоювати значення за допомогою fopen (). Крім того, саме тому, що на початку роботи програми ці покажчики файлів створюються автоматично, в кінці роботи вони і закриваються автоматично. Так що і не намагайтеся самостійно їх закрити.

Зв'язок з консольним введенням / висновком

У мові С консольний і файловий ввід / вивід не надто відрізняються один від одного. Функції консольного введення / виведення, описані в розділі 8. насправді направляють результати своїх операцій на один з потоків - stdin або stdout. і по суті, кожна з них є спеціальною версією відповідної файлової функції. Функції консольного введення / виведення для того і існують, щоб було зручно саме програмісту.

Як говорилося в попередньому розділі, введення / виведення на консоль можна виконувати за допомогою будь-якої файлової функції мови С. Однак для вас може бути сюрпризом, що, виявляється, операції введення / виводу на дискових файлах можна виконувати за допомогою функції консольного введення / виведення, наприклад , printf (). Справа в тому, що всі функції консольного введення / виведення, про які йшлося в главі 8. виконують свої операції з потоками stdin і stdout. У середовищах, що підтримують перенаправлення вводу / виводу, це рівнозначно тому, що stdin або stdout можуть бути перенаправлені на пристрій, відмінне від клавіатури або екрана. Проаналізуйте, наприклад, наступну програму:

Припустимо, що ця програма називається TEST. При її нормальному виконанні на екран виводиться підказка, потім Новомосковскется рядок, введений з клавіатури, і, нарешті, цей рядок виводиться на екран. Однак в середовищах, в яких підтримується перенаправлення вводу / виводу, один з потоків stdin або stdout (або обидва одночасно) можна перенаправити в файл. Наприклад, в середовищі DOS або Windows наступний запуск TEST

призводить до того, що висновок цієї програми буде записаний у файл на ім'я OUTPUT. А наступний запуск TEST

направляє потік stdin в файл на ім'я INPUT, а потік стандартного виведення - в файл на ім'я OUTPUT.

Коли С-програма завершується, то все переслані потоки повертаються в стану, які були встановлені за замовчуванням.

Перенаправлення стандартних потоків: функція freopen ()

Для перенаправлення стандартних потоків можна скористатися функцією freopen (). Ця функція пов'язує наявний потік з новим файлом. Так що вона цілком може зв'язати з новим файлом і стандартний потік. Ось прототип цієї функції:

де ім'я файлу - це покажчик на ім'я файлу, який потрібно зв'язати з потоком, на який вказує покажчик потік. Файл відкривається в режимі режим; цей параметр може приймати ті ж значення, що і відповідний параметр функції fopen (). Якщо функція freopen () виконалася успішно, то вона повертає потік. а якщо зустрілися помилки, - то NULL.

У наступній програмі показано використання функції freopen () для перенаправлення стандартного потоку виводу stdout в файл з ім'ям OUTPUT.