Як ми зазначили в Розділі 1, бібліотека втілює просту модель текстового вводу і виводу. Текстовий потік складається з послідовності рядків, кожний рядок закінчується знаком нового рядка. Якщо система не працює в такий спосіб, бібліотека зробить все від неї залежне, щоб здавалося, що все саме так і є. Наприклад, бібліотека може перетворювати повернення каретки і переведення рядка на символ нового рядка при вводі і в зворотньому напрямку при виводі.
Найпростіший механізм вводу — це читати по одному символу за один раз зі стандартного вводу, як правило це клавіатура, за допомогою getchar:
int getchar(void)
getchar повертає неступний введений знак кожний раз як її викликано, або EOF, коли вона зіткнулася з кінцем файла. Символічну константу EOF визначено в <stdio.h>. Це значення, типово, дорівнює -1, але краще вживати EOF, щоб не залежати від певного значення. В багатьох середовищах, клавіатуру можна замінити на файл скориставшись з умовного знака <, який позначає перенаправлення вводу: якщо програма prog послуговується getchar, тоді команда
prog <infile
змушує prog читати символи з infile, натомість. Перемкнення вводу відбувається в такий спосіб, що сама програма prog знає про зміну; зокрема, ланцюжок «<infile» не включається як аргумент командного рядка в argv. Заміна вводу також залишається невидимою, якщо ввід надходить з іншої програми через конвеєр: на деяких системах, команда
otherprog | prog
запускає дві програми, otherprog і prog, і передає через конвеєр стандартний вивідotherprog стандартному вводу prog.
Функція
int putchar(int)
використовується для виводу: putchar(c) виводить символ c на стандартний вивід, типово, це екран. putchar повертає виведений символ, або EOF, якщо відбулася помилка. Знову ж таки, вивід можна перенаправити у файл за допомогою >filename. Якщо програма використовуєputchar, команда
prog >outfile
запише стандартний вивід до outfile, натомість. Якщо підтримуються конвеєри,
prog | anotherprog
поміщає стандартний вивід prog у стандартний ввід anotherprog. Вивід, спричиненийprintf, також знаходить свій шлях до стандартного пристрою виводу. Виклики putchar іprintf можуть чергуватися — вивід відбувається в тій послідовності, в якій виклики відбуваються.
Кожний вихідний файл, що згадує якусь з функцій бібліотеки вводу/виводу, повинен містити рядок
#include <stdio.h>
перед тим як їх вживати. Коли назву файла заголовка включено в дужки < та >, пошук такого відбувається в стандартному наборі місць в системі (наприклад, на UNIX, типовим каталогом є/usr/include).
Багато програм читають тільки один потік вводу і записують тільки один виводу; для таких програм буде цілком додстатньо здійснення вводу і виводу за допомогою getchar, putchar іprintf, або, принаймні, цього вистачить для початку. Це особливо так, якщо перенаправлення використовується для під'єднання виводу однієї програми до вводу іншої. Наприклад, розглянемо програму lower, яка переводить свій ввід у нижній регістр:
#include <stdio.h>
#include <ctype.h>
main() /* lower: переводить ввід у нижній регістр */
{
int c
while ((c = getchar()) != EOF)
putchar(tolower(c));
return 0;
}
Функцію tolower визначено в <ctype.h>, вона перетворює літеру верхнього регістру у нижній і повертає решту символів незмінними. Як ми зазначили раніше, «функції» на зразокgetchar і putchar з <stdio.h> і tolower з <ctype.h> часто являються макросами, щоб запобігти витраті ресурсів на виклик функції для кожного символу. Ми покажемо як здійснити це в Розділі 8.5. Незалежно від того, як втілено функції <ctype.h> на окремих машинах, програми, що використовують їх, не вимушені знати деталей про набір символів.
Вправа 7-1. Напишіть програму, яка би перетворювала літери верхнього регістру на нижній або нижнього на верхній в залежності від того, за яким ім'ям її було викликано, на що вказуватимеargv[0].