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

Ввод и вывод в языке C

Embed Size (px)

DESCRIPTION

Ввод и вывод в языке C. Одной из основных особенностей языка Си по отношению к большинству других языков программирования высокого уровня является полное отсутствие в нем предопределенных операторов ввода/вывода - PowerPoint PPT Presentation

Citation preview

Page 1: Ввод и вывод в языке  C

Ввод и вывод в языке C Одной из основных особенностей языка Си по отношению к

большинству других языков программирования высокого уровня является полное отсутствие в нем предопределенных операторов ввода/вывода

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

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

Page 2: Ввод и вывод в языке  C

При разработке и эксплуатации программного обеспечения операции ввода/вывода играют столь же большую роль, как, например, инструкции управления или способы описания оперативных структур данных

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

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

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

Page 3: Ввод и вывод в языке  C

В современных вычислительных системах внешние устройства, с которыми приходится поддерживать обмен, по выполняемым функциям делятся на две категории

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

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

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

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

Page 4: Ввод и вывод в языке  C

Файлы данных и каталоги файлов

Файлами принято называть поименованные наборы данных на внешних носителях

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

По характеру хранимой информации различают файлы данных и файлы-каталоги (директории)

Первые из них содержат данные, непосредственно используемые прикладными программами, включая исходные тексты, объектные и загрузочные модули самих этих программ

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

Page 5: Ввод и вывод в языке  C

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

Тот каталог, который находится на высшем уровне иерархической организации, носит название корневого каталога

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

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

Page 6: Ввод и вывод в языке  C

В операционной среде WINDOWS не существует какой-либо предопределенной внутренней структуры файлов

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

Файлы первого типа обычно называют текстовыми файлами и они могут быть визуализированы, например, на экране видеотерминала

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

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

Page 7: Ввод и вывод в языке  C

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

Так, например, в текстовом режиме комбинация символов CR/LF (hex-коды 0xD и 0xA соответственно) преобразуется при вводе в единственный символ LF. В процессе же вывода выполняется обратное преобразование. При работе в двоичном режиме подобные преобразования не выполняются

Page 8: Ввод и вывод в языке  C

Стандартные функции для работы с файлами и каталогами

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

ввод/вывод потоком символов операции обмена низкого уровня управление файлами и каталогами

Организация обмена со стандартными внешними устройствами рассмотрена в следующем параграфе

Page 9: Ввод и вывод в языке  C

1. Ввод/вывод потоком символов

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

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

После завершения работы с потоком, его следует закрыть, используя функцию fclose. В противном случае это сделает операционная система по окончании работы программы

Page 10: Ввод и вывод в языке  C

Операции чтения и записи для потока выполняются, начиная с текущей позиции указателя, смещая последний на соответствующее число позиций

Используя функцию fseek, указатель можно установить в произвольную позицию файла перед выполнением очередной операции, а функция rewind позиционирует указатель на начало файла

Предварительные описания функций ввода/вывода потоком, а также определения соответствующих констант, типов и структур помещены в файл stdio.h, который необходимо включить в программу при помощи директивы препроцессора #include. В этом же файле описаны некоторые полезные константы

EOF - определение значения возврата при достижении конца файлаNULL - указатель на нульFILE - структура, которая содержит информацию о потокеBUFSIZ - размер буфера в байтах

Page 11: Ввод и вывод в языке  C

Имя функции и назначение: fopen - открывает файл с заданным именем для ввода/вывода потоком

Формат и описание аргументов:

FILE *fopen(pathname, type) const char *pathname; /* Имя открываемого файла */ const char *type; /* Тип доступа к файлу */

Параметр type представляет собой строку символов и определяет характер доступа к файлу:

"r" - существующий текстовый файл открыть для чтения (файл должен существовать)

"w" - текстовый файл открыть для записи (в случае существования файла его содержимое разрушается)

"a" - текстовый файл открыть для записи в конец файла (добавление) (если файл не существует он создается)

"r+" - существующий файл открыть для чтения и записи (файл должен уже существовать)

"w+" - пустой текстовый файл открыть для чтения и записи (в случае существования файла его содержимое разрушается)

Page 12: Ввод и вывод в языке  C

Добавление символа "b" в конец каждой из этих строк позволяет открыть двоичный файл для выполнения соответствующих операций

Функция возвращает указатель типа FILE при нормальном завершении операции и NULL в случае возникновения ошибки

Пример использования:

#include <stdio.h>

void main()

{ FILE *stream;

if ((stream = fopen("data", "r")) == NULL)

printf("Ошибка при открытии файла"); ......................................

}

Page 13: Ввод и вывод в языке  C

Имя функции и назначение:

fclose - закрывает файл, предварительно открытый для ввода/вывода потоком,

fcloseall() - закрывает все потоки

Формат и описание аргументов:

int fclose(stream)

FILE *stream; /* Указатель на открытый файл */

Page 14: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

void main()

{ FILE *stream;

stream = fopen("data", "w+"); ........................... ...........................

fclose(stream);

}

Page 15: Ввод и вывод в языке  C

Имя функции и назначение:

feof - проверяет возникновение ситуации "конец файла" при вводе/выводе потоком

Формат и описание аргументов:

int feof(stream) FILE *stream; /* Указатель на открытый файл */

Возвращаемое значение отлично от нуля при попытке чтения за пределами файла и равно нулю в противном случае

Page 16: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

char string[100];

FILE *stream;

void process(char*);

void main()

{ while (!feof(stream))

if (fscanf(stream, "%s", string))process(string);

}

Page 17: Ввод и вывод в языке  C

Имя макроса и назначение:

getc(stream) - читает очередной символ из входного потока и увеличивает значение указателя

getchar() - аналогично, но с потоком из стандартного ввода

Имя функции и назначение:

fgetc - читает очередной символ из входного потока и увеличивает значение указателя. То же, что и getc и getchar, но являются функциями, а не макросами

Формат и описание аргументов:

int fgetc(stream) FILE *stream; /* Указатель на открытый файл */

Возвращаемое значение равно коду прочитанного символа при нормальном завершении операции и EOF в случае возникновения ошибки или при достижении конца файла

Page 18: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

void main() { char buffer[81]; int i, ch; FILE *stream; for (i=0; i<80&&(ch=fgetc(stream))!= EOF;i++) buffer[i]=ch; buffer[i] = '\0‘ }

Page 19: Ввод и вывод в языке  C

Формат и описание аргументов:

char *fgets(string, n, stream) char *string; int n; FILE *stream; /* Указатель на открытый файл */

Возвращаемое значение равно указателю на строку string при нормальном завершении операции и NULL в случае возникновения ошибки или при достижении конца файла

Пример использования:

#include <stdio.h> void main() { char line[100], *result; FILE *stream; ... result = fgets(line, 100, stream); ... }

Page 20: Ввод и вывод в языке  C

Имя функции и назначение:

getw - читает из входного потока очередное целое число, заданное в двоичном формате, и увеличивает значение указателя

Формат и описание аргументов:

int getw(stream)

FILE *stream; /* Указатель на открытый файл */

Возвращаемое значение равно прочитанному целому числу при нормальном завершении операции и EOF в случае возникновения ошибки или при достижении конца файла

Page 21: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

void main(){ int ivalue; FILE *stream; ... ivalue = getw(stream); ... }

Page 22: Ввод и вывод в языке  C

Имя функции и назначение: fputc - записывает символ в выходной поток и увеличивает значение указателя

Формат и описание аргументов:

int fputc(c, stream) int c; /* Выводимый символ */

FILE *stream; /* Указатель на открытый файл */

Возвращаемое значение равно коду записанного символа при нормальном завершении операции и EOF в случае возникновения ошибки

Page 23: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h> void main() { char buffer[81]; int i; FILE *stream; ... for (i = 0; i < 81 && buffer[i] != '\0'; i++) fpufc(buffer[i], stream); ... }

Page 24: Ввод и вывод в языке  C

Имя функции и назначение: fputs - копирует строку символов в выходной поток

Формат и описание аргументов:

int fputs(string, stream) const char *string;

FILE *stream;

Возвращаемое значение равно коду последнего символа строки при нормальном завершении операции, нулю для пустой строки и EOF в случае возникновения ошибки

Page 25: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

void main()

{ FILE *stream;

...

fputs("This is a string", stream);

...

}

Page 26: Ввод и вывод в языке  C

Имя функции и назначение:

putw - записывает в выходной поток двоичное представление целого числа и увеличивает значение указателя

Формат и описание аргументов:

int putw(binint, stream)

int binint;

FILE *stream; /* Указатель на открытый файл */

Возвращаемое значение равно binint при нормальном завершении операции и EOF в случае возникновения ошибки

Page 27: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

void main() { FILE *stream; ... putw(0347, stream); ... }

Page 28: Ввод и вывод в языке  C

Имя функции и назначение: fscanf - читает данные из входного потока и заносит их в ячейки памяти, определяемые аргументами функции

Формат и описание аргументов:

int fscanf(stream, fstring <, argument ...>) FILE *stream; /* Указатель на открытый файл */ const char *fstring; /* Строка управления форматом */

Строка string управления форматом определяет способ интерпретации входных данных. Она может содержать следующие поля:

пробелы, символы табуляции (\t) или перехода на новую строку (\n), которые позволяют читать без сохранения любые комбинации соответствующих символов из входного потока;

произвольные печатаемые символы ASCII, кроме знака процента (%), использование которых позволяет читать без сохранения соответствующие им символы из входного потока;

спецификации формата, начинающиеся со знака процента (%) и требующие преобразования прочитанных данных к заданному типу

Page 29: Ввод и вывод в языке  C

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

Всякая спецификация формата в общем случае имеет следующий вид:

%<*><width><h|l|L>type

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

Символ преобразования, соответствующий полю type, определяет тип очередного элемента данных, читаемого из входного потока. Этим элементом может быть отдельный символ ASCII, строка символов или число (целое или вещественное). Ниже приведена таблица символов преобразования, а также указан тип отвечающего каждому из них аргумента

Page 30: Ввод и вывод в языке  C

Символ Элемент входного потока Тип аргумента

d десятичное целое указатель на на int

D десятичное целое указатель на long

o восьмеричное целое указатель на на int

O восьмеричное целое указатель на long

X шестнадцатеричное целое указатель на на int

X шестнадцатеричное целое указатель на long

i десятичное, восьмеричное или шестнадцатеричное целое

указатель на на int

I десятичное, восьмеричное или шестнадцатеричное целое

указатель на long

u десятичное целое без знака указатель на unsigned int

U десятичное целое без знака указатель на unsigned long

e, f, g, E

вещественное число указатель на float

c символ ASCII указатель на char

s строка символов указатель на массив элементов типа char

p значение вида xxxx:yyy где x и y есть шестнадцатеричные цифры

указатель на адрес

Page 31: Ввод и вывод в языке  C

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

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

Дополнительные спецификаторы h, l и L могут быть использованы для модификации типа аргумента, определенного полем type. Их действие распространяется лишь на длину соответствующего аргумента (short или long)

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

При попытке чтения за пределами файла функция возвращает значение EOF

Page 32: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

void main() { char sym, string[81]; int ival; long lval; float fval; FILE *stream; ............................. stream = fopen("data", "r"); fscanf(stream, "%c", &sym); fscanf(stream, "%s", string); fscanf(stream, "%d", &ival); fscanf(stream, "%ld", &lval); fscanf(stream, "%f", &fval); ............................. }

Page 33: Ввод и вывод в языке  C

Имя функции и назначение: fprintf - записывает форматированные данные в выходной поток

Формат и описание аргументов:

int fprintf(stream, fstring <, argument ...>) FILE *stream; /* Указатель на открытый файл */

const char *fstring; /* Строка управления форматом */

Строка fstring управления форматом определяет способ преобразования данных при выводе. Она может включать в себя обычные символы, копируемые в выходной поток, Esc-последовательности и спецификации формата, начинающиеся со знака процента (%).

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

Page 34: Ввод и вывод в языке  C

Всякая спецификация формата в общем случае имеет следующий вид:

%<flags><width><.precision><h|l|L>type

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

Символ преобразования, соответствующий полю type, определяет тип очередного элемента данных, записываемого в выходной поток. Этим элементом может быть отдельный символ ASCII, строка символов или число (целое или вещественное). Ниже приведена таблица символов преобразования, имеющих специальное значение

Page 35: Ввод и вывод в языке  C

Символ Аргумент Формат вывода

d, I целое число десятичное целое со знаком

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

o целое число восьмеричное целое без знака

x целое число шестнадцатеричное целое без знака,

использующее abcdef

X целое число шестнадцатеричное целое без знака,

использующее ABCDEF

f вещественное число вещественное целое со знаком с фиксированной точкой

e,E вещественное число вещественное целое со знаком в экспоненциальной форме

g,G вещественное число вещественное целое со знаком с фиксированной точкой или в экспоненциальной форме в зависимости от величины порядка

c cимвол ASCII отдельный символ

s указатель типа char строка символов

Page 36: Ввод и вывод в языке  C

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

Дополнительный флаг в виде знака номера (#) может использоваться для вывода начального нуля в восьмеричном формате и пары 0x или 0X в шестнадцатеричном формате, а также для обязательной печати десятичной точки при выводе вещественных чисел даже при нулевом значении поля precision

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

Page 37: Ввод и вывод в языке  C

Для замены пробелов на нули необходимо снабдить параметр width префиксом нуль (0). При отсутствии этого параметра в строке формата он автоматически получает некоторое стандартное значение

Целочисленный положительный параметр precision определяет минимальное количество печатаемых цифр в записи целого числа (при использовании символов преобразования i, d, u, o, x или X), количество цифр справа от десятичной точки при печати вещественных чисел (преобразование по форматам f, e, E, g или G) или максимальное количество символов в строке (при выводе по формату s). В случае отсутствия, этот параметр заменяется некоторым стандартным значением, зависящим от типа выводимого элемента данных

Дополнительные спецификаторы h, l и L могут быть использованы для задания длины выводимого аргумента (short или long)

Возвращаемое функцией fprintf значение равно количеству напечатанных символов

Page 38: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h> #define MAX 100void main() { int i; float length[MAX], width[MAX]; FILE *printer; .................................. printer = fopen("prn", "w"); fprintf(printer, "\t\t\t*** Результаты расчета ***\n\

n"); for (i = 0; i < MAX; i++) fprintf(printer, "%3d length = %6.3f, width = %6.3f\

n", length[i], width[i]); .................................. }

Page 39: Ввод и вывод в языке  C

Имя функции и назначение: fseek - перемещает указатель текущей позиции файла

Формат и описание аргументов:

int fseek(stream, offset, origin) FILE *stream; /* Указатель на открытый файл */ long offset; /* Смещение в байтах от origin */ int origin; /* Начальная позиция указателя */

Эта функция перемещает указатель, связанный с открытым файлом, на offset байт вперед или назад относительного заданного параметром origin начала отсчета. Последний может быть одной из следующих символических констант, определенных в файле stdio.h:

SEEK_SET - начало файлаSEEK_CUR - текущая позиция указателяSEEK_END - конец файла

Page 40: Ввод и вывод в языке  C

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

Пример использования:

#include <stdio.h>

void main() { int result; FILE *stream; stream = fopen("data", "r"); ........................... result = fseek(stream, 0L, SEEK_SET); ........................... }

Page 41: Ввод и вывод в языке  C

Имя функции и назначение: rewind - устанавливает указатель текущей позиции на начало файла

Формат и описание аргументов:

void rewind(stream)

FILE *stream; /* Указатель на открытый файл */

Эта функция не возвращает никакого значения в точку вызова

Page 42: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h> void main() { int dat_1 = 1, dat_2 = 7, dat_3, dat_4; FILE *stream; stream = fopen("data", "w+"); /*Запись данных в файл */ fprintf(stream, "%d %d", dat_1, dat_2); /* Установка указателя на начало */ rewind(stream); fscanf(stream, "%d %d", &dat_3, &dat_4); ............................... }

Page 43: Ввод и вывод в языке  C

2. Операции ввода/вывода низкого уровня

Функции ввода/вывода низкого уровня осуществляют обмен с файлами или периферийными устройствами путем прямого обращения к соответствующим функциям операционной системы (системным вызовам)

Они не предоставляют возможности буферизации информации при пересылке и не обеспечивают преобразования данных из внутреннего машинного представления в текстовый формат

Page 44: Ввод и вывод в языке  C

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

Новый файл может быть создан путем использования функции creat.

Обе эти функции возвращают в точку вызова целочисленный параметр (file handle), который следует использовать для ссылки на открытый файл во всех последующих операциях ввода/вывода низкого уровня или при управлении указателем текущей позиции

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

Page 45: Ввод и вывод в языке  C

При начале работы 5 file handle уже автоматически открыты

stdin 0stdout 1stderr 2stdaux 3stdprn 4

Операции чтения и записи низкого уровня выполняются функциями read и write соответственно начиная с текущей позиции указателя

Используя функцию lseek, указатель можно установить в произвольную позицию файла перед выполнением очередной операции ввода/вывода

Проверка выхода за конец файла осуществляется функцией eof

Page 46: Ввод и вывод в языке  C

Предварительные описания функций ввода/вывода низкого уровня помещены в файл io.h. Кроме этого, файлы fcntl.h, sys\types.h и sys\stat.h содержат определения символических констант, используемых отдельными функциями

Для нормальной работы программы все эти файлы необходимо включить в ее исходный текст при помощи директивы препроцессора #include

open - открыть файлclose - закрыть файлcreate - создать файлeof - проверка на конец файлаlseek - переместить указатель файла в заданное положениеread - читать данные из файлаwrite - записать данные в файл

tell - получить текущее положение указателя файла

Page 47: Ввод и вывод в языке  C

Имя функции и назначение:

int open(pathname,oflag,[,pmode])

Формат и описание аргументов:

int open(pathname,oflag,[,pmode]);

char *pathname; /* Имя файла */

int oflag;

int pmode;

Page 48: Ввод и вывод в языке  C

Значения oflag :

O_APPEND - присоединить к концу файлаO_CREATE - создать и открыть новый файл для записи (если файл существует ничего не делать)O_EXCL - используется только с O_CREATE, чтобы вернуть значение ошибки если имя файла уже существуетO_RDONLY - открыть файл только для чтенияO_RDWR - открыть файл как для чтения, так и для записиO_TRUNC - O_WRONLY - открыть файл, только для записиO_TEXT - открыть в текстовом видеO_BINARY - открыть файл в двоичном виде

Значения pmode : (используется только с O_CREATE , если файл уже существует pmode игнорируется)

S_IWRITES_IREADS_IWRITE: S_IREAD

Возвращает handle для открытых файлов, или 1, если ошибка

Page 49: Ввод и вывод в языке  C

Пример использования:

#include <fcntl.h> #include <sys\types.h> #include <io.h>#include <stdlib.h>

void main() { int ih; ih = open(“info.dat”,O_RDONLY); }

Page 50: Ввод и вывод в языке  C

Имя функции и назначение: int read(handle,buffer,count)

Функция пытается прочитать count байтов из файла, связанного с handle из buffer. Операция чтения начинается с текущей позиции указателя файлов

Формат и описание аргументов:

int read(handle,buffer,count);

int handle;

char *buffer;

unsigned int count;

Возвращает число действительно прочитанных символов, 0 - если была попытка прочитать конец файла, -1 – ошибка

Page 51: Ввод и вывод в языке  C

Пример использования:

#include <fcntl.h>#include <sys\types.h> #include <io.h> #include <stdlib.h>

void main() { int fh; unsigned int nbytes = 60000, bytesread; if ((fh = open(“c:\data\conf.dat”,O_RDONLY)) == -1) { perror(“попытка открыть входной файл неудачна”); exit(1); } if ((bytesread = read(fh,buffer,nbytes)) = = -1) perror(“ “); else printf(“прочитано %d байтов из файла \n”,bytesread); ... close(fh); }

Page 52: Ввод и вывод в языке  C

Имя функции и назначение:

int close(handle);

Функция закрывает файл, связанный с handle Возвращает: 0 - если файл успешно закрыт -1 если handle

неправильный

Page 53: Ввод и вывод в языке  C

3. Управление файлами и каталогами

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

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

В этом разделе приведены краткие сведения о некоторых функциях рассматриваемой группы. Их предварительные описания помещены в стандартные файлы stdio.h и direct.h, которые при необходимости следует включить в исходный текст программы, используя директиву препроцессора #include

Page 54: Ввод и вывод в языке  C

Имя функции и назначение:

remove - удаляет файл с заданным именем

Формат и описание аргументов:

int remove(pathname)

const char *pathname; /* Полное имя удаляемого файла */

Возвращаемое значение равно нулю при нормальном завершении операции и -1 в случае отсутствия в каталоге файла с заданным именем или запрете на его удаление (read-only file)

Page 55: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

void main()

{ int result;

..............

result = remove("c:\\myfile");

if (result == -1)

printf("Ошибка при удалении файла");

..............

}

Page 56: Ввод и вывод в языке  C

Имя функции и назначение:

rename - изменяет имя существующего файла или каталога

Формат и описание аргументов:

int rename(oldname, newname) const char *oldname; /* Старое имя файла */ const char *newname; /* Новое имя файла */

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

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

Page 57: Ввод и вывод в языке  C

Пример использования:

#include <stdio.h>

void main() { int result; .............. result = rename("c:\\programs\myprog", "c:\\

myprog"); .............. }

Page 58: Ввод и вывод в языке  C

Имя функции и назначение:

chdir - изменяет текущий каталог

Формат и описание аргументов:

int chdir(pathname) char *pathname; /* Имя нового текущего каталога */

Возвращаемое значение равно нулю при нормальном изменении текущего каталога и -1 в случае возникновения ошибки

Пример использования:

#include <direct.h> void main() { ............ chdir("..\\.."); ........... }

Page 59: Ввод и вывод в языке  C

Имя функции и назначение:

mkdir - создает новый каталог

Формат и описание аргументов:

int mkdir(pathname) char *pathname; /* Имя создаваемого каталога */

Возвращаемое значение равно нулю при нормальном завершении операции и -1 в противном случае.

Пример использования:

#include <direct.h> void main() { int result; .................... result = mkdir("b:\\newdir"); .................... }

Page 60: Ввод и вывод в языке  C

Имя функции и назначение:

rmdir - удаляет существующий каталог

Формат и описание аргументов:

int rmdir(pathname)

char *pathname; /* Имя удаляемого каталога */

Удаляемый этой функцией каталог должен быть пустым и не может являться текущим или корневым каталогом.

Возвращаемое значение равно нулю при нормальном завершении операции и -1 в случае возникновения ошибки.

Page 61: Ввод и вывод в языке  C

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

устройствами

В операционной среде всевозможные внешние устройства последовательного доступа (терминалы, устройства печати, графопостроители и т. д.) рассматриваются как специальные файлы

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

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

Связь имен специальных файлов с конкретными внешними устройствами обычно устанавливается на уровне базовой системы ввода/вывода (BIOS)

Page 62: Ввод и вывод в языке  C

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

Имя файла Устройство Режим доступа

stdin стандартное устройство ввода (обычно клавиатура терминала)

чтение

stdout стандартное устройство вывода (обычно экран терминала)

запись

stderr стандартное устройство для сообщений об ошибках (обычно экран терминала)

запись

stdaux стандартное вспомогательное устройство (обычно устройство, подключенное по последовательному интерфейсу COM1)

чтение/запись

stdprn стандартное устройство печати запись

Page 63: Ввод и вывод в языке  C

Предопределенные имена специальных файлов по существу являются указателями на структуру FILE и их допустимо использовать на месте параметра stream во всех функциях ввода/вывода потоком. Так, например, для печати сообщения на экране терминала достаточно воспользоваться функцией fprintf, задав в качестве ее первого параметра имя stdout:

fprintf(stdout, "Это стандартное устройство вывода");

С другой стороны, ввод символа, поступившего от клавиатуры терминала, можно выполнить при помощи функции fgetc, адресовав ее к стандартному устройству ввода stdin:

sym = fgetc(stdin);

Page 64: Ввод и вывод в языке  C

Заметим, однако, что не все операции, определенные для обычных файлов, имеют смысл для стандартных устройств ввода/вывода

Например, следующее обращение к функции fscanf

fscanf(stdout, "%d", &intval);

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

Ошибочным также будет обращение к функции fseek при любом указатели на специальный файл

Page 65: Ввод и вывод в языке  C

Для удобства работы со стандартными устройствами stdin и stdout в состав библиотеки языка Си дополнительно включены функции, специально ориентированные на обмен с этими устройствами

Их имена во многом схожи с именами рассмотренных функций ввода/вывода потоком и приведены в следующей таблице

Каждая из упомянутых здесь функций семантически подобна соответствующей ей общей функции и имеет те же самые аргументы, исключая указатель на структуру FILE. Их предварительные описания также помещены в файл stdio.h (кроме описания функции getch() , которое находится в файле conio.h).

Page 66: Ввод и вывод в языке  C

Имя функции Назначение Эквивалентное обращение

getch() читает очередной символ от клавиатуры терминала без эха на экране

нет

fgetchar() getchar()

читают очередной символ со стандартного устройства ввода

fgetc(stdin)

fputchar(s) putchar(s)

записывают символ s на стандартное устройство вывода

fputc(s, stdout)

gets(str) читает строку символов str со стандартного устройства ввода

fgets(str, 256, stdin)

puts(str) копирует строку символов str на стандартное устройство вывода

puts(str, stdout)

scanf(...) читает форматированные данные со стандартного устройства ввода

fscanf(stdin, ...)

printf(...) записывает форматированные данные на стандартное устройство вывода

fprintf(stdout, ...)

Page 67: Ввод и вывод в языке  C

Операции ввода/вывода через порты

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

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

Одни порты предназначены для буферирования данных и называются буферными портами или портами данных

Другие служат для хранения информации о состоянии устройства или интерфейса и носят название портов состояния

Третьи, называемые портами управления, используются для получения команд от центрального процессора

Page 68: Ввод и вывод в языке  C

Стандартная библиотека компилятора предоставляет пользователям две функции с именами inp() и outp() , осуществляющие прямой обмен информацией с портами микропроцессора

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

Предварительные описания функций inp() и outp() помещены в файл conio.h

Page 69: Ввод и вывод в языке  C

Имя функции и назначение:

inp - читает один информационный байт через входной порт с заданным номером

Формат и описание аргументов:

int inp(port) unsigned port; /* Номер опрашиваемого порта */

Пример использования:

#include <conio.h> void main() { char result; unsigned port = 0x64; result = inp(port); printf("Содержимое порта 64H равно %0x\n", (int)result); }

Page 70: Ввод и вывод в языке  C

Имя функции и назначение:

outp - записывает один информационный байт в выходной порт с заданным номером

Формат и описание аргументов:

int outp(port, value) unsigned port; /* Номер выходного порта */ int value; /* Выводимое значение */

Возвращаемое функцией outp значение равно параметру value

Пример использования:

#include <conio.h> void main() { unsigned port = 0x64; outp(port, 0x03); }

Page 71: Ввод и вывод в языке  C

Имя функции и назначение:

cputs(str) - записывает строку (записанную вместе с символом конца строки) на консоль

Формат и описание аргументов:

void cputs(str); char *str; /* Выводимая строка */

Пример использования:

#include <conio.h> void main() { char *buffer = "Вставьте диск с данными в драйвер A:\R\N"); cputs(buffer); }

Page 72: Ввод и вывод в языке  C

Имя функции и назначение:

kbhit() - проверяет консоль на нажатие клавиши

Возвращает ненулевое значение, если клавиша была нажата, 0 иначе

Формат и описание аргументов:

int kbhit()

Page 73: Ввод и вывод в языке  C

Пример использования:

#include <conio.h>

void main() { int result; result = kbhit(); }

Если результат ненулевой, введенный символ находится в буфере. Он может быть извлечен getch или getc

Если getch или getc были вызваны без проверки посредством kbhit , программа перейдет в ожидание нажатия клавиши