1 / 73

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

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

beau-wooten
Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

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

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

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

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

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

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

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

  10. Операции чтения и записи для потока выполняются, начиная с текущей позиции указателя, смещая последний на соответствующее число позиций • Используя функцию fseek, указатель можно установить в произвольную позицию файла перед выполнением очередной операции, а функция rewind позиционирует указатель на начало файла • Предварительные описания функций ввода/вывода потоком, а также определения соответствующих констант, типов и структур помещены в файл stdio.h, который необходимо включить в программу при помощи директивы препроцессора #include. В этом же файле описаны некоторые полезные константы EOF - определение значения возврата при достижении конца файла NULL - указатель на нуль FILE - структура, которая содержит информацию о потоке BUFSIZ - размер буфера в байтах

  11. Имя функции и назначение:fopen - открывает файл с заданным именем для ввода/вывода потоком • Формат и описание аргументов: FILE *fopen(pathname, type) const char *pathname; /* Имя открываемого файла */ const char *type; /* Тип доступа к файлу */ • Параметр type представляет собой строку символов и определяет характер доступа к файлу: • "r" - существующий текстовый файл открыть для чтения (файл должен существовать) • "w" - текстовый файл открыть для записи (в случае существования файла его содержимое разрушается) • "a" - текстовый файл открыть для записи в конец файла (добавление) (если файл не существует он создается) • "r+" - существующий файл открыть для чтения и записи (файл должен уже существовать) • "w+" - пустой текстовый файл открыть для чтения и записи (в случае существования файла его содержимое разрушается)

  12. Добавление символа "b" в конец каждой из этих строк позволяет открыть двоичный файл для выполнения соответствующих операций • Функция возвращает указатель типа FILE при нормальном завершении операции и NULL в случае возникновения ошибки • Пример использования: #include <stdio.h> void main() { FILE *stream; if ((stream = fopen("data", "r")) == NULL) printf("Ошибка при открытии файла"); ...................................... }

  13. Имя функции и назначение: fclose - закрывает файл, предварительно открытый для ввода/вывода потоком, fcloseall() - закрывает все потоки • Формат и описание аргументов: int fclose(stream) FILE *stream; /* Указатель на открытый файл */

  14. Пример использования: #include <stdio.h> void main() { FILE *stream; stream = fopen("data", "w+"); ........................... ........................... fclose(stream); }

  15. Имя функции и назначение: feof - проверяет возникновение ситуации "конец файла" при вводе/выводе потоком • Формат и описание аргументов: int feof(stream) FILE *stream; /* Указатель на открытый файл */ • Возвращаемое значение отлично от нуля при попытке чтения за пределами файла и равно нулю в противном случае

  16. Пример использования: #include <stdio.h> char string[100]; FILE *stream; void process(char*); void main() { while (!feof(stream)) if (fscanf(stream, "%s", string))process(string); }

  17. Имя макроса и назначение: getc(stream) - читает очередной символ из входного потока и увеличивает значение указателя getchar()- аналогично, но с потоком из стандартного ввода • Имя функции и назначение: fgetc - читает очередной символ из входного потока и увеличивает значение указателя. То же, что и getc и getchar, но являются функциями, а не макросами • Формат и описание аргументов: int fgetc(stream) FILE *stream; /* Указатель на открытый файл */ • Возвращаемое значение равно коду прочитанного символа при нормальном завершении операции и EOF в случае возникновения ошибки или при достижении конца файла

  18. Пример использования: #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‘ }

  19. Формат и описание аргументов: 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); ... }

  20. Имя функции и назначение: getw - читает из входного потока очередное целое число, заданное в двоичном формате, и увеличивает значение указателя • Формат и описание аргументов: int getw(stream) FILE *stream; /* Указатель на открытый файл */ • Возвращаемое значение равно прочитанному целому числу при нормальном завершении операции и EOF в случае возникновения ошибки или при достижении конца файла

  21. Пример использования: #include <stdio.h> void main() { int ivalue; FILE *stream; ... ivalue = getw(stream); ... }

  22. Имя функции и назначение:fputc - записывает символ в выходной поток и увеличивает значение указателя • Формат и описание аргументов: int fputc(c, stream) int c; /* Выводимый символ */ FILE *stream; /* Указатель на открытый файл */ • Возвращаемое значение равно коду записанного символа при нормальном завершении операции иEOF в случае возникновения ошибки

  23. Пример использования: #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); ... }

  24. Имя функции и назначение:fputs - копирует строку символов в выходной поток • Формат и описание аргументов: int fputs(string, stream) const char *string; FILE *stream; • Возвращаемое значение равно коду последнего символа строки при нормальном завершении операции, нулю для пустой строки и EOF в случае возникновения ошибки

  25. Пример использования: #include <stdio.h> void main() { FILE *stream; ... fputs("This is a string", stream); ... }

  26. Имя функции и назначение: putw - записывает в выходной поток двоичное представление целого числа и увеличивает значение указателя • Формат и описание аргументов: int putw(binint, stream) int binint; FILE *stream; /* Указатель на открытый файл */ • Возвращаемое значение равно binint при нормальном завершении операции и EOF в случае возникновения ошибки

  27. Пример использования: #include <stdio.h> void main() { FILE *stream; ... putw(0347, stream); ... }

  28. Имя функции и назначение:fscanf - читает данные из входного потока и заносит их в ячейки памяти, определяемые аргументами функции • Формат и описание аргументов: int fscanf(stream, fstring <, argument ...>) FILE *stream; /* Указатель на открытый файл */ const char *fstring; /* Строка управления форматом */ • Строка string управления форматом определяет способ интерпретации входных данных. Она может содержать следующие поля: • пробелы, символы табуляции (\t) или перехода на новую строку (\n), которые позволяют читать без сохранения любые комбинации соответствующих символов из входного потока; • произвольные печатаемые символы ASCII, кроме знака процента (%), использование которых позволяет читать без сохранения соответствующие им символы из входного потока; • спецификации формата, начинающиеся со знака процента (%) и требующие преобразования прочитанных данных к заданному типу

  29. Аргументы функции fscanf являются указателями на ячейки памяти, куда необходимо поместить прочитанные значения, и должны иметь тот же самый тип, который задан соответствующими спецификациями в строке управления форматом • Всякая спецификация формата в общем случае имеет следующий вид: %<*><width><h|l|L>type • где угловыми скобками (<>) обозначены необязательные элементы конструкции. Отдельные поля спецификации могут быть символами или числами, задающими конкретный способ преобразования данных при вводе • Символ преобразования, соответствующий полю type, определяет тип очередного элемента данных, читаемого из входного потока. Этим элементом может быть отдельный символ ASCII, строка символов или число (целое или вещественное). Ниже приведена таблица символов преобразования, а также указан тип отвечающего каждому из них аргумента

  30. Символ звездочка (*), возможно входящий в спецификацию формата, заставляет систему обмена проигнорировать очередной элемент данных заданного типа во входном потоке • Необязательное поле width представляет собой положительное десятичное число, задающее максимальное количество символов, читаемых из входного потока и интерпретируемых в соответствии со спецификатором type • Дополнительные спецификаторы h,l и L могут быть использованы для модификации типа аргумента, определенного полем type. Их действие распространяется лишь на длину соответствующего аргумента (short или long) • Возвращаемое функцией fscanf значение равно количеству прочитанных и преобразованных в соответствии с заданным форматом полей входного потока. • При попытке чтения за пределами файла функция возвращает значение EOF

  31. Пример использования: #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); ............................. }

  32. Имя функции и назначение:fprintf - записывает форматированные данные в выходной поток • Формат и описание аргументов: int fprintf(stream, fstring <, argument ...>) FILE *stream; /* Указатель на открытый файл */ const char *fstring; /* Строка управления форматом */ • Строка fstring управления форматом определяет способ преобразования данных при выводе. Она может включать в себя обычные символы, копируемые в выходной поток, Esc-последовательности и спецификации формата, начинающиеся со знака процента (%). • Аргументы функции fprintf являются простыми переменными или указателями, задающими набор выводимых значений.

  33. Всякая спецификация формата в общем случае имеет следующий вид: %<flags><width><.precision><h|l|L>type где угловыми скобками (<>) обозначены необязательные элементы конструкции. Отдельные поля спецификации могут быть символами или числа ми, задающими конкретный способ преобразования данных при выводе • Символ преобразования, соответствующий полю type, определяет тип очередного элемента данных, записываемого в выходной поток. Этим элементом может быть отдельный символ ASCII, строка символов или число (целое или вещественное). Ниже приведена таблица символов преобразования, имеющих специальное значение

  34. Символы, занимающие поле flags в строке формата, позволяют управлять размещением выводимой информации в пределах поля, заданного параметром width, а также определяют способ вывода чисел со знаком. Так, знак минус (-) в этом случае требует выравнивания печатаемых символов по левой границе поля width (по умолчанию производится выравнивание по правой границе), а знак плюс (+) заставляет выводить со знаком (+ или -) как положительные, так и отрицательные числа • Дополнительный флаг в виде знака номера (#) может использоваться для вывода начального нуля в восьмеричном формате и пары 0x или 0X в шестнадцатеричном формате, а также для обязательной печати десятичной точки при выводе вещественных чисел даже при нулевом значении поля precision • Параметр width является целым положительным десятичным числом, определяющим минимальное количество позиций, отводимых под соответствующий элемент данных в выходном потоке. Если количество символов в выводимом значении меньше width, то осуществляется его расширение пробелами слева или справа в зависимости от значения поля flags

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

  36. Пример использования: #include <stdio.h> #define MAX 100 void 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]); .................................. }

  37. Имя функции и назначение:fseek - перемещает указатель текущей позиции файла • Формат и описание аргументов: int fseek(stream, offset, origin) FILE *stream; /* Указатель на открытый файл */ long offset; /* Смещение в байтах от origin */ int origin; /* Начальная позиция указателя */ • Эта функция перемещает указатель, связанный с открытым файлом, на offset байт вперед или назад относительного заданного параметром origin начала отсчета. Последний может быть одной из следующих символических констант, определенных в файле stdio.h: SEEK_SET - начало файлаSEEK_CUR - текущая позиция указателяSEEK_END - конец файла

  38. Заметим, что допустимым является позиционирование указателя за пределами конца файла, однако его перемещение за начало файла приводит к ошибке. Возвращаемое значение равно нулю при нормальном завершении операции и отлично от нуля в противном случае • Пример использования: #include <stdio.h> void main() { int result; FILE *stream; stream = fopen("data", "r"); ........................... result = fseek(stream, 0L, SEEK_SET); ........................... }

  39. Имя функции и назначение:rewind - устанавливает указатель текущей позиции на начало файла • Формат и описание аргументов: void rewind(stream) FILE *stream; /* Указатель на открытый файл */ • Эта функция не возвращает никакого значения в точку вызова

  40. Пример использования: #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); ............................... }

  41. 2. Операции ввода/вывода низкого уровня • Функции ввода/вывода низкого уровня осуществляют обмен с файлами или периферийными устройствами путем прямого обращения к соответствующим функциям операционной системы (системным вызовам) • Они не предоставляют возможности буферизации информации при пересылке и не обеспечивают преобразования данных из внутреннего машинного представления в текстовый формат

  42. Перед обращением к существующему файлу его необходимо предварительно открыть при помощи функции open для ввода, вывода или выполнения обеих этих операций в текстовом или двоичном режиме • Новый файл может быть создан путем использования функции creat. • Обе эти функции возвращают в точку вызова целочисленный параметр (file handle), который следует использовать для ссылки на открытый файл во всех последующих операциях ввода/вывода низкого уровня или при управлении указателем текущей позиции • После завершения работы с файлом, его нужно закрыть путем вызова функции close. В противном случае это сделает операционная система по окончании работа программы

  43. При начале работы 5 file handle уже автоматически открыты stdin 0stdout 1stderr 2stdaux 3stdprn 4 • Операции чтения и записи низкого уровня выполняются функциями readи write соответственно начиная с текущей позиции указателя • Используя функцию lseek, указатель можно установить в произвольную позицию файла перед выполнением очередной операции ввода/вывода • Проверка выхода за конец файла осуществляется функцией eof

  44. Предварительные описания функций ввода/вывода низкого уровня помещены в файл io.h. Кроме этого, файлы fcntl.h, sys\types.h и sys\stat.h содержат определения символических констант, используемых отдельными функциями • Для нормальной работы программы все эти файлы необходимо включить в ее исходный текст при помощи директивы препроцессора #include open - открыть файлclose - закрыть файлcreate - создать файлeof - проверка на конец файлаlseek - переместить указатель файла в заданное положениеread - читать данные из файлаwrite - записать данные в файл tell - получить текущее положение указателя файла

  45. Имя функции и назначение: int open(pathname,oflag,[,pmode]) • Формат и описание аргументов: int open(pathname,oflag,[,pmode]); char *pathname; /* Имя файла */ int oflag; int pmode;

  46. Значения 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, если ошибка

  47. Пример использования: #include <fcntl.h> #include <sys\types.h> #include <io.h> #include <stdlib.h> void main() { int ih; ih = open(“info.dat”,O_RDONLY); }

  48. Имя функции и назначение:int read(handle,buffer,count) • Функция пытается прочитать count байтов из файла, связанного с handle из buffer. Операция чтения начинается с текущей позиции указателя файлов • Формат и описание аргументов: int read(handle,buffer,count); int handle; char *buffer; unsigned int count; • Возвращает число действительно прочитанных символов, 0 - если была попытка прочитать конец файла, -1 – ошибка

More Related