Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Лекция: функции и переключение ввода-вывода



 

-Ввод и вывод одного символа.

-Буферы.

-Чтение одной строки.

-Чтение файла.

-Переключение и работа с файлами.

 

Ввод и вывод одного символа

 

В данном разделе мы рассмотрим функции, применяемые при вводе и выводе. Кроме того, мы коснемся других аспектов этого понятия. Под функциями ввода-вывода подразумеваются функции, которые выполняют транспортировку данных в программу и из нее. Мы уже использовали две такие функции: printf( ) и scanf( ). Теперь рассмотрим несколько других возможностей, предоставляемых языком Си.

Функции ввода-вывода не входят в определение языка Си. Их разработка возложена на программистов, реализующих компилятор с языка Си. С другой стороны, выгода использования стандартного набора функций ввода-вывода на всех системах очевидна. Это дает возможность писать переносимые программы, которые легко можно применять на разных машинах. В языке Си имеется много функций ввода-вывода такого типа, например printf( ) и scanf( ). Ниже мы рассмотрим функции getchar( ) и putchar( ).

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

Функция getchar( ) получает один символ, поступающий с пульта терминала (и поэтому имеющий название), и передает его выполняющейся в данный момент программе. Функция putchar( ) получает один символ, поступающий из программы, и пересылает его для вывода на экран. Рассмотрим пример программы, которая принимает один символ с клавиатуры, и выводит его на экран:

/*ввод-вывод*/

#include < stdio.h>

main( )

{

char ch;

ch=getchar( ); /***1***/

putchar(ch); /***2***/

}

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

putchar('D');

putchar('\n');

putchar('\007');

putchar(ch); /* переменная типа char */

putchar(getchar( ));

Модифицируем нашу программу:

#include < stdio.h>

main( )

{

putchar(getchar( ));

}

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

 

Буферы

 

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

 

Зачем нужны буферы?

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

Рассмотрим вывод на печать групп символов. Желательно, чтобы в любой момент можно было остановить работу программы. Для этого напишем программу так, чтобы она прекращала работу при получении какого-нибудь специального символа, например "! ":

/* ввод-вывод */

/* ввод и печать символов до поступления

завершающего символа */

#include < stdio.h>

#define STOP '! ' /*дает символу '! ' символическое имя */

main( )

{

char ch;

ch=getchar( ); /***9***/

while(ch! = STOP) { /***10***/

putchar( ch); /***11***/

ch=getchar( ); /***12***/

}

}

В данном примере при первом прохождении тела цикла функция putchar( ) получает значение своего аргумента в результате выполнения оператора, расположенного в строке 9. В дальнейшем, вплоть до завершения работы цикла, значением этого аргумента является символ, передаваемый программе функцией getchar, расположенной в строке 12. Цикл while будет осуществлять чтение и печать символов до тех пор, пока не поступит признак STOP.

! Программа, приведенная ниже, делает то же самое, но стиль ее написания лучше отвечает духу языка Си:

/* ввод-вывод */

#include < stdio.h>

#define STOP '! '

main( )

{

char ch;

while ((ch=getchar( ))! = STOP) /***8***/

putchar(ch);

}

Одна строка 8 этой программы заменяет строки 9, 10, 12 предыдущей программы.

 

Чтение одной строки

 

Усложним пример ввода-вывода:

/* подсчет символов */

#include < stdio.h>

#define STOP '! '

main( )

{

char ch;

/*инициализация счетчика символов 0 */

int count = 0;

while ((ch=getchar( ))! = STOP) {

putchar(ch);

count++; /* прибавить 1 к счетчику */

}

printf(" \n Всего было прочитано %d символа.\n",

count);

}

Если мы хотим просто подсчитать число введенных символов без отображения их на экране, функцию putchar( ) можно опустить.

Заменим признак окончания ввода данных, используем символ новая строка \n. Для этого нужно переопределить признак STOP:

#define STOP '\n'

Символ новая строка пересылается при нажатии клавиши Enter. Предположим, что мы внесли указанное изменение в программу " подсчет символов", а затем при выполнении ввели следующую строку:

На экране тридцать четыре символа.[Enter]

В ответ на экране появятся следующие строки:

На экране тридцать четыре символа.

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

 

Чтение файла

 

Если нам нужно читать большие порции данных, например из файла, каким должен быть признак STOP? Это должен быть такой символ, который обычно не используется в тексте и, следовательно, не приводит к ситуации, когда он случайно встретится при вводе, и работа программы будет остановлена раньше, чем бы мы хотели. Файлом можно назвать участок памяти, в который помещена некоторая информация. Обычно файл хранится в некоторой долговременной памяти, например на гибких или жестких дисках или на магнитной ленте. Чтобы отмечать, где кончается один файл и начинается другой, полезно иметь специальный символ, указывающий на конец файла, чтобы отмечать конец файла и начинать другой. Это должен быть символ, который не может появиться где-то в середине файла. Решением указанной проблемы служит введение специального признака, называемого " End-of-File", конец файла, или EOF. Выбор конкретного признака EOF зависит от типа системы. Он может состоять даже из нескольких символов. Обычно определение EOF содержится в файле < stdio.h>. Общеупотребительным является определение

#define EOF (-1)

Пример:

/* ввод-вывод_ф */

#include < stdio.h>

main( )

{

int ch;

while ((ch = getchar( ))! = EOF)

putchar(ch);

}

Это надо помнить:

  1. Не нужно самим определять признак EOF. Он описан в файле < stdio.h>.
  2. Мы можем не интересоваться фактическим значением символа EOF, поскольку директива #define, имеющаяся в файле < stdio.h>, позволяет нам использовать его символическое представление.

Мы изменили в нашей программе тип переменной ch с char на int. Это мы сделали, потому что значением переменных типа char является целое без знака в диапазоне от 0 до 255, а признак EOF может иметь числовое значение -1. Эта величина недопустима для переменной типа char. Функция getchar( ) фактически возвращает значение типа int, поэтому она в состоянии прочесть символ EOF.

Переменная ch целого типа никак не может повлиять на работу функции putchar( ). Она просто выводит на печать символьный эквивалент значения аргумента.

При работе с данной программой, когда символы вводятся с клавиатуры, необходимо уметь вводить признак EOF. В большинстве реализаций операционной системы UNIX, например, ввод [CTRL/d] (нажать на клавишу [d], держа нажатой клавишу [CTRL]) интерпретируется как признак EOF. Во многих микрокомпьютерах для той же цели используется знак [CTRL/z].

Пусть мы ввели фразу с клавиатуры. Приведем результат работы программы " ввод-вывод_ф" в системе, с буферизованным вводом:

Спрос на высокопрофессиональных ИТ-специалистов

Спрос на высокопрофессиональных ИТ-специалистов

растет как со стороны государственных, так и

частных компаний растет как со стороны

государственных, так и частных компаний

[CTRL/z]

Каждый раз при нажатии клавиши Enter производится обработка символов, попавших в буфер, и копия строки выводится на печать. Это продолжается до тех пор, пока мы не введем признак EOF. Программа " ввод-вывод_ф" осуществляет вывод на экран символов независимо от того, откуда они поступают. Наша программа могла бы просматривать содержимое файлов, создавать новые файлы и получать копии файлов. Решение этих проблем - в управлении вводом и выводом.

 


Поделиться:



Последнее изменение этой страницы: 2017-04-13; Просмотров: 479; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.031 с.)
Главная | Случайная страница | Обратная связь