Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DOROGOVA.pdf
Скачиваний:
245
Добавлен:
05.06.2015
Размер:
853.4 Кб
Скачать

11. Ввод-вывод данных

Выводом называется процедура переноса данных из памяти компьютера на внешние устройства. При вводе данных напротив, информация извне вносится в память компьютера.

Данные можно ввести с клавиатуры или из файла на диске, вывести их на экран, отпечатать на принтере, кроме того, данные можно сохранить на магнитной ленте или послать по телефонной линии через модем или по факсу.

При выводе данные не удаляются из памяти компьютера, не изменяется способ их хранения, компьютер просто копирует данные и посылает их на соответствующие устройства. При вводе данные также копируются в память компьютера, а информация на внешнем устройстве не претерпевает никаких изменений.

Вязыке С ввод и вывод данных осуществляется с помощью библиотечных функций, которые работают как с консолью, так и с файлами.

Консоль - это устройство для управления компьютерной системой, это может быть клавиатура, экран дисплея, принтер или любое другое устройство, связывающее пользователя с компьютером.

Файл - это способ хранения информации вне памяти компьютера. В настоящее время существует множество устройств для хранения информации, многие из них доступны через файлы, в принципе, можно сказать, что файловым может быть любое устройство, представимое в цифровом виде. Например, принтер при соблюдении определенных правил работы может считаться файловым устройством. Но наиболее часто программист работает с файлами на жестком диске компьютера.

Вотличие от переменной, файл (в частности, его имя) имеет смысл вне конкретной программы. Работа

сфайлами реализуется средствами операционных систем. Более подробно мы рассмотрим работу с файлами позднее.

Различают буферизованный и небуферизованный (прямой) ввод/вывод данных.

Небуферизованный ввод/вывод характерен тем, что символ немедленно доступен ожидающей программе. Примером могут служить функции ch=getch(), putch(ch) из библиотеки conio.

При буферизованном вводе/выводе символы сначала помещаются в специальную область памяти,

называемую буфером. Здесь они накапливаются до тех пор, пока не нажата клавиша ENTER или полностью не заполнится буфер. Только после этого накопленный блок данных становится доступным программе.

Большинство библиотечных функций языка С и С++ работают с буферизацией, например getchar(),

putchar(ch).

Зачем нужны буферы? Одни устройства производят запись данных в буфер, а другие - чтение из него. Программа, выполнившая запись в буфер, может немедленно продолжать работу, не ожидая, пока данные будут обработаны внешним устройством. Это очень важно для эффективной работы компьютера, так как, внешние устройства работают значительно медленнее памяти компьютера. Таким образом, буферизация позволяет выполнять параллельно вывод и обработку данных.

Если необходимо передать данные между устройствами, работающими с различными скоростями, также необходим буфер. Каждое устройство работает с буфером со своей скоростью, в то время как в буфере, по необходимости, накапливаются данные. Такой метод работы называется синхронизацией передачи информации.

Термин буферизация чаще используется применительно к компьютерной технике, в программировании же чаще используется термин поток данных.

В общем случае поток это механизм преобразования значений различного типа в последовательность символов (вывод) и наоборот (ввод). Но можно рассматривать поток как синоним буфера данных. Потоки могут быть буферизованные и небуферизованные, форматированные и неформатированные.

Буфер, который поставляет данные компьютеру, называется входным потоком, буфер, который выводит данные из компьютера, называется выходным потоком. При работе программы потоки связываются с тем или иным физическим устройством, программист же, используя библиотечные функции, всегда работает с потоком. Итак, для того, чтобы вывести или ввести данные в компьютер нужно воспользоваться одной из многочисленных библиотечных функций.

Отметим одно интересное свойство функций ввода языка С. Когда данные вводятся с клавиатуры, они отображаются на экране монитора, при этом в программе не используются никакие функции вывода на экран, это "явление" называется эхопечать. Эхопечать используется в большинстве функций ввода, таких

как getchar(), gets(), scanf().

Мы рассмотрим наиболее простые и популярные из них, полный перечень библиотечных функций можно найти в справочниках по библиотечным функциям языка С или С++. Таких справочников очень много, как в электронном виде, так и в печатном виде, например книги известного автора, признанного специалиста по С и С++ Герберта Шилдта:

Герберт Шилдт. Справочник программиста С/С++.

Герберт Шилдт. Полный справочник по С++.

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

11.1.Ввод-вывод данных на консоль. Библиотека stdio

11.1.1.Стандартные потоки библиотеки stdio

Библиотека - это отдельный файл, прилагающийся к компилятору языка С, содержащий функции для решения распространенных задач. В языке С реализованы многочисленные библиотечные функции для разнообразных целей, наиболее полезные, на взгляд автора функции, выделены в специальный раздел пособия, их описание вы найдете в приложении А.

Функции ввода-вывода размещены в нескольких библиотеках, наиболее популярные из которых stdio, conio, iostream.

Рассмотрим некоторые библиотечные функции библиотек stdio и conio.

После подключения библиотеки stdio с помощью директивы #include в начале работы программы, автоматически открываются три заранее определенных потока:

stdin - входной поток данных;

stdout - выходной поток данных;

stderr - поток ошибок.

По умолчанию эти потоки связаны с консолью:

stdin

- с клавиатурой;

stdout

- с терминалом.

Следует отметить, что потоки можно перенаправить и на другие устройства, например в файл.

11.1.2. Чтение и запись символов

Простейшими консольными функциями ввода-вывода являются функции getchar() и getch(), считывающие символ с клавиатуры, и функция putchar(), выводящая символ на экран. Все эти функции имеют только один аргумент (параметр), а это означает, что они могут отображать только один объект.

Функции getchar() и getch() возвращают целое число, в младшем байте которого содержится код символа, соответствующего нажатой клавише (старший байт содержит нулевое значение).

Если при вводе возникает ошибка, функции возвращают константу EOF(EOF равна -1). Формат функций ввода выгладит так:

int getchar (void) int getch (void)

Безразлично, к какому типу (char или int) вы отнесете вводимый символ, что обусловлено двойственностью символьных данных в языке С (о двойственности смотрите ниже по тексту). Обратите внимание на то, что для сохранения введенной информации необходима операция присваивания, так как функции getch() и getchar() рассматривается программой как значение введенной переменной.

Однако на этом сходство обеих функций кончается, далее остановимся на их отличиях. Прототип функции getchar() находится в библиотеке stdio.h. Функция getchar() вводит символ из потока stdin, который имеет буфер на одну строку, поэтому она ничего не возвращает до тех пор, пока вы не нажмете клавишу ENTER, кроме того, функция getchar() осуществляет эхопечать.

Прототип функции getch() находится в библиотеке conio.h. Функция getch() вводит символ с консоли без буферизации и эхопечати. Это означает, что символ доступен в программе сразу же после того, как он введен с клавиатуры.

Пример:

#include <stdio.h> #include <conio.h>

void main()

{

char simbol1; char simbol2;

simbol1 = getchar(); simbol2 = getch();

}

Для того чтобы записать информацию в перемекнную simbol1, после ввода первого символа необходимо нажать ENTER, второй значащий символ запишется в переменную simbol2 сразу после его

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

ввода с клавиатуры. Причем первый введенный символ мы увидим на экране, а второй нет. Чтобы проверить правильность ввода можно использовать инструкцию:

printf ("\nsim1=%c sim2=%c\n",simbol1,simbol2);

Следующий пример показывает посимвольную работу с текстом.

Пример. Ввести текст с клавиатуры, признаком конца ввода считать точку, подсчитать количество введенных символов.

#include <stdio.h> void main()

{

char z[100]; int i;

printf(“Напишите предложение с точкой в конце:\n”) for (i=0; z[i] != '. '; i++)

z[i]=getchar();

printf(«Количество символов=%d»,i);

}

Следует обратить внимание на то, что при работе с текстом, используя getchar(), мы не получаем строку символов, так как отсутствует признак конца строки '\0'. Для того, чтобы не нарушать стандартов языка, следует добавить символ '\0' после окончания ввода текстовой информации.

void main()

{

char z[100]; int i;

printf(“Напишите предложение с точкой в конце:\n”) for (i=0; z[i] != '. '; i++)

z[i]=getchar();

printf("Количество символов (без признака "конец строки") =%d",i); z[i] = '\0';

}

Итак, добавление '\0' к массиву z[] превращает последовательность символов в строку.

Остановимся на двойственности символьных данных. Функции ввода-вывода для символьных данных были сконструированы таким образом, чтобы они могли работать и с целочисленным типом данных. Компилятор самостоятельно преобразует данные типа int в буквы.

Пример: Двойственность символьных данных void main()

{

int letter; letter='G'; putchar(letter);

}

Несмотря на то, что переменная letter определена как целочисленная, ей может быть присвоен символ. Программа при этом будет компилироваться, и выполняться без ошибок. Право выбора, использовать ли переменные типа char или int, остается за вами.

Рассмотрим функцию вывода символа на консоль - putchar(). Несмотря на то, что эта функция наряду с символами может получать и целочисленный аргумент, ей можно передавать только символьные значения. Иначе говоря, целочисленные значения трактуются как коды символов, и, следовательно, на экран выводится только младший байт аргумента.

Функция putchar() возвращает либо код символа, либо константу EOF, если произошла ошибка.

Формат функции putchar() выглядит так: int putchar (int c)

Параметром функции может являться:

символьный литерал;

символьная константа;

символьная переменная.

Пример: Составить слово из отдельных символов и вывести его на экран. #define sim2 'Е'

void main()

{char sim3; sim3='С';

printf ("Составим слово ЛЕС из отдельных символов:") putchar('Л'); \\ символьный литерал;

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

putchar(sim2);

\\ символьная константа;

putchar(sim3);

\\ символьная переменная

}

Обратите внимание на то, что при работе с символьными данными (литералами или константами) их следует заключать в одинарные кавычки.

11.1.3. Чтение и запись строк

Консольные функции gets() и puts() позволяют считывать и записывать строки.

Функция gets() считывает строку символов с клавиатуры, и размещает её по адресу, указанному в аргументе, eё прототип находится в библиотеке stdio. Поскольку функция работает с буфером, на время её работы выполнение программы приостанавливается, она ожидает ввода текста с клавиатуры, признаком окончания ввода является клавиша ENTER, после чего строка, введенная пользователем, присваивается переменной в качестве значения.

Следует обратить внимание на одну важную особенность функции gets(), несмотря на то, что нажата клавиша ENTER, в конец строки ставится не символ перехода на новую строку, а нулевой символ '\0'- признак конца строки.

При наборе строки допускается её редактирование, ошибки можно исправить с помощью клавиши

BACKSPACE.

Вкачестве аргумента следует указывать массив символов, в который и будут записаны символы, введенные пользователем.

Пример: Ввести строку текста в массив, вывести строку на экран. #include <stdio.h>

void main()

{

char buffer[125]; printf("Наберите строку:"); gets(buffer);

printf("Была введена строка: %s\n", buffer);

}

Функция gets() будет рассматривать символы, введенные с клавиатуры, как значение строковой переменной с именем buffer. Следует помнить, что один элемент необходим для нулевого символа '\0', поэтому указывайте длину массива на единицу больше максимально возможной строки. Например, если вы хотите ввести в переменную buffer строку, состоящую из 125 символов, то определяйте массив:

char buffer[126];

Функция puts() выводит на экран строку символов и переводит курсор на следующую строку, её eё

прототип находится в библиотеке stdio. Если при выводе возникла ошибка, то функция возвращает

константу EOF.

Вкачестве параметра могут выступать:

Строковый литерал.

Строковая константа.

Строковая переменная.

Хорошо известное приветствие можно записать с помощью функции puts следующим образом: puts("Hellow world!!!");// это строковый литерал

Пример: Вывести фразу из нескольких строк на экран дисплея. #define str1 "Добро пожаловать "

void main()

{

char str2[]="в мир программирования !"; puts(str1); // строковая константа puts(str2); // строковая переменная:

}

Отметим, что литерал - это конкретный набор символов, который вводится непосредственно в инструкции языка С вместо имени константы или переменной.

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

11.1.4. Обзор консольных функций ввода-вывода

Сведения об основных функциях ввода вывода приведены в таблице 11.1.

Таблица 11.1

Функция

Операция

getchar ()

Считывает символ с клавиатуры, выводит его на

экран, ожидает перехода на новую строку

 

getche()

Считывает символ с клавиатуры и выводит его на

экран, не ожидает перехода на новую строку.

 

getch()

Считывает символ с клавиатуры и не выводит его на

экран, не ожидает перехода на новую строку.

 

putchar()

Выводит символ на экран.

 

Окончание таблицы 11.1

Функция

Операция

gets()

Считывает строку с клавиатуры, ожидает перехода

на новую строку.

 

puts()

Выводит строку на экран и переводит курсор на

следующую строку.

 

11.1.5. Форматированный ввод-вывод данных

Функции printf() и scanf() выполняют форматированный ввод-вывод на консоль, иначе говоря, они могут считывать и записывать данные в заданном формате и с комментариями. Обе функции могут оперировать любыми встроенными типами данных, включая символы, строки и числа.

Функцию printf часто называют «выводом с форматированием».

Формат вызова: #include <stdio.h>

рrintf ("управляющая строка", аргумент _1, аргумент _2,...);

Первый аргумент функции, в кавычках называют строкой форматирования, так как она указывает "как нужно производить вывод", то есть определяет формат вывода, последующие аргументы указывают "что нужно выводить".

Строка форматирования содержит элементы трех типов:

обычные символы, которые просто копируются в стандартный выходной поток (выводятся на экран дисплея);

команды форматирования, которые определяют тип отображаемого аргумента;

управляющие символьные последовательности, которые осуществляют форматирование.

Команда форматирования начинается с символа %, за которым следует код формата. Основные форматы представлены в таблице 11.2. и таблице 11.3.

Количество аргументов после строки форматирования должно совпадать с количеством команд форматирования, причем совпадение обязательно и в порядке их следования.

Таблица 11.2

Команды форматирования функции printf

%c

Символ

%s

строка символов

%d, %i

десятичное целое

со знаком

 

%u

десятичное целое

без знака

 

%f

вещественное число

(значение с плавающей точкой)

 

%e

Экспоненциальное представление

вещественного числа

 

%o

восьмеричное число

без знака

 

%x

шестнадцатеричное.

число без знака

 

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

При форматировании необходимо не только выводить символы, но и управлять выводом, например, переводить строки, делать отступы и так далее. Для этой цели служат управляющие символы, уже рассмотренные нами ранее, часто их называют escape-последовательностями. Напомним, что каждая последовательность начинается с символа обратной косой черты (\), который указывает на то, что символы, расположенные за ним, являются управляющими. Когда компилятор встречает обратную косую черту, он не отображает следующие символы, а выполняет действие, на которое они указывают.

Пример: Вывод значений трех переменных на экран терминала.

Для большей наглядности различные элементы функции printf() выделим различными шрифтами.

вывод текста(комментарий);

управляющие последовательности;

команды форматирования;

имена переменных (объекты вывода).

printf ("Вывод трех целых чисел: \n\tx=%d\t y=%d\tz=%d", x , y , z);

Комбинация символов %d служит своего рода указателем места в строке, куда необходимо вставить значение переменной при печати.

Пусть 5,15,25 - это значения переменных x,y,z, тогда на экране будет отображено следующее:

Вывод трех целых чисел:

 

x=5

y=15

z=25

Функция scanf считывает данные с клавиаруры и сохраняет информацию в переменных, заданных аргументами, перечисленными в списке аргументов.

Формат вызова: #include <stdio.h>

scanf ("форматирование", аргумент _1, ...);

Аналогично функции printf() используются команды форматирования.

Таблица 11.3

 

Команды форматирования функции scanf()

%c

символ

%s

строка символов

%d, %i

Десятичное целое со знаком

%u

Десятичное целое без знака

%f, %e

вещественное число

%o

восьмеричное число

%x

шестнадцатеричное число.

Пример: Вввод различных данных.

#include <stdio.h> int i;

float fp; char c, s[81];

scanf("%d %f %c %s", &i, &fp, &c, &s);

Чтобы ввести длинное целое поставьте перед форматом модификатор l или L, чтобы прочитать короткое целое - модификатор h или H. Эти модификаторы можно использовать с форматами: d, i, o, u, x

Пример:

#include <stdio.h> int x ;

scanf ("%ld",&x);

В переменную x с клавиатуры будет введено длинное целое число.

Пример: Пробельные символы (пробел, табуляция, новая строка и тому подобное) используются для разделения полей при вводе данных.

scanf ("%d%d",&x,&y);

если входной поток состоит из 3-х символов -

10<пробел> 20 или 10 <табуляция> 20, то:

число 10 будет введено в переменную x;

число 20 будет введено в переменную y;

Пример 3: Несмотря на то, что пробельные символы используются для разделения полей, при вводе символьных данных они читаются, подобно любому другому символу.

scanf ("%с%с%с",&x,&y,&z);

если входной поток состоит из 3-x символов:

а <пробел> б, то:

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]