Ввод, вывод и стандартная библиотека функций ввода-вывода icon

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



НазваниеВвод, вывод и стандартная библиотека функций ввода-вывода
страница1/3
Дата конвертации16.09.2012
Размер0.57 Mb.
ТипДокументы
  1   2   3
1. /Troy/1.doc
2. /Troy/10.doc
3. /Troy/11.doc
4. /Troy/12.doc
5. /Troy/13.doc
6. /Troy/14.doc
7. /Troy/15.doc
8. /Troy/16.doc
9. /Troy/2.doc
10. /Troy/3.doc
11. /Troy/4.doc
12. /Troy/Издательство.doc
13. /Troy/ОГЛАВЛЕНИЕ.doc
14. /Troy/ПРЕДИСЛОВИЕ.doc
Программирование для ibm pc
Ввод, вывод и стандартная библиотека функций ввода-вывода
Библиотека языка си: общеупотребительные функции и макроопределения в этой главе сосредоточимся на тех функциях и макроопределениях, не «занимающихся»
Использование функций на языке ассемблера в программах на языке си
Создание библиотек и пользование ими
Указатель на символ. Например, объявление
Указатель на функцию, и последующий вы­зов функции, на которую показывает этот указатель. Второй прием основан на применении рекурсивных функций в языке Си
Более развитые приемы отладки программ
Введение в язык си
Структура и конструкция программы на языке си
Типы и структуры данных
Для персонального компьютера ibm pc
Введение в язык си часть 1
Книга предназначена для обучения языку Си и рассчитана на читателя, име­ющего основные представления о компьютере. Однако когда речь заходит об использовании специфических свойств ibm pc, то приводятся соответствующие разъяснения

ГЛАВА 10


ВВОД, ВЫВОД И СТАНДАРТНАЯ БИБЛИОТЕКА ФУНКЦИЙ ВВОДА-ВЫВОДА

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

Хотя грамматика языка Си и не выделяет функции ввода-вывода, тем не менее существует их устоявшийся перечень. Кроме того, подкомитетом Американского национального института стандартов X3J11, который работает над предложениями по стандарту языка Си, опубликован предполагаемый стандартный перечень функций ввода-вывода (см. [C-Language ]). Первая часть настоящей главы посвящена представ­лению общепринятых функций ввода-вывода.

Другие библиотечные функции, нередко поставляемые вместе с компиляторами языка Си, например функции для манипулирования строками, математические функции и функции управления динамической памятью, будут обсуждаться в гл. 11 и 14 соответственно. В приложении 5 приведен полный перечень функций язы­ка Си, обсуждающихся в этой книге.

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

ЧАСТЬ 1

Функции ввода-вывода можно разбить на два широких класса. К первому относятся небольшое число примитивных функций ввода-вывода, называемых функциями системного уровня. На основе этих функций строятся функции более высокого уровня, называемые функциями стандартного (или файло­вого) ввода-вывода. Функции стандартного ввода-вывода получили свое имя от принятого в операционной системе UNIX соглашения по стандартному вводу-выводу, которое теперь частично поддерживается операционной систе­мой PC DOS (см. гл. 1). Обсуждение библиотеки ввода-вывода начнем с функций стандартного ввода-вывода.

10.1. СТАНДАРТНЫЕ ВВОД, ВЫВОД И ПЕРЕАДРЕСАЦИЯ ВВОДА-ВЫВОДА

Первоначально язык Си разрабатывался как средство реализации операционной системы UNIX и ее служебных программ. Основной целью разработки как опе­рационной системы UNIX, так и языка Си было создание комплекса простых инстру­ментальных средств программирования, из которых можно было бы составлять пакеты для решения различных прикладных задач. Универсальность этих средств обеспечива­лась благодаря применению стандартных ввода, вывода и переадресации ввода-выво­да, что частично поддерживается и в операционной системе DOS.

Мы уже пользовались функциями (или макроопределениями — это зависит от способа реализации) getchar и printf как в программе вычисления выражений, так и в программе управления портфелем акций. Эти функции соответственно считы­вают данные с клавиатуры и выводят данные на экран дисплея IBM PC. Будем называть клавиатуру стандартным устройством ввода, а экран - стандартным устройством вывода.










При работе с операционной системой PC-DOS 2.0 или с ее более поздними версиями, а также с операционными системами, разработанными на основе опе­рационной системы UNIX, можно переадресовать стандартный ввод и вывод другим устройствам. Например, стандартный вывод команды DIR на IBM PC мо­жет быть переадресован в дисковый файл с именем out.dat с помощью команды A>dir > out.dat

Ввод для программы more может быть переадресован из дискового файла input.dat с помощью команды

A>more > input.dat

Наконец, стандартный вывод одной программы может быть переадресован стан­дартному вводу другой программы с помощью операции конвейера. Чтобы прочитать каталог файлов гибкого диска, отсортировать его по алфавиту и поместить результат в дисковый файл myfiles.txt, достаточно ввести команду A>dlr I sort > myfiles.txt

Вертикальная черта I называется операцией конвейера. Она означает, что вывод программы dir становится вводом программы sort. Далее, вывод программы sort пере­адресуется в дисковый файл. Программы, которые воспринимают данные с устройства стандартного ввода, модифицируют их и направляют на стандартное устройство вы­вода (например, программа sort), нередко называются фильтрами. Фильтры представляют собой инструментальные средства, из которых можно образовывать кон­вейер для решения различных задач.

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

Многие из компиляторов языка Си, разработанных для операционной системы PC-DOS 2.0 (или для более поздних версий), поддерживают соглашения о стан­дартном вводе-выводе, что позволяет программам на языке Си пользоваться преимуществами переадресации и конвейеризации. При обсуждении функций стандартного ввода-вывода будем считать, что имеем дело именно с таким компилятором.

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

10.2. ФАЙЛОВЫЙ И СТАНДАРТНЫЙ ВВОД-ВЫВОД

Для осуществления файлового ввода-вывода требуются два файла: 1)файл заголовка, содержащий общие имена и обычно имеющий имя stdio.h; 2)собственно библиотека, которая иногда имеет имена libc.a, libc.lib или lc.lib. Обычно любой модуль, в котором содержатся вызовы функций файлового ввода-вывода, должен начинаться с одной из следующих директив препроцессора: #Include "stdio.h" или < #include .stdio.h>

Некоторые компиляторы, особенно рассчитанные для работы под управлением опе­рационной системы UNIX, используют правую директиву, которая дает компилятору указание искать этот файл в заданной файловой области диска. Большинство реализаций компиляторов для IBM PC используют левую директиву, которая указывает, что поиск файла заголовка должен проводиться в текущей файловой области. При работе под управлением операционной системы PC-DOS 2.0 или более поздних версий в директиве можно указывать полный путь к файлу с помощью имен областей файлов (если Ваш компилятор обеспечивает такую воз­можность). Файл заголовка stdio.h содержит общие структуры данных и имена, определенные с помощью директив #define. Они требуются при использовании функций файлового ввода-вывода. Вы можете распечатать файл stdio.h и позна­комиться с его содержанием.

Прочитав содержимое своего файла заголовка stdio.h, среди разных имен Вы должны обнаружить идентификаторы, показанные в табл. 10.1.



Первый идентификатор, FILE, представляет собой имя структуры. Эта структура используется функциями ввода-вывода для хранения информации, связанной с ус­тройством или файлом. Если компилятор поддерживает соглашения об устройствах стандартного ввода, вывода, и устройстве для сообщений об ошибках, то Вы обна­ружите три идентификатора: stdin, stdout и stderr, которые являются указателями на структуры типа FILE. При вызове программы эти структуры заполняются таким образом, чтобы устройствами стандартного ввода-вывода служили клавиатура и дисплей. Директивами #define определены также имена NULL, EOF и BUFSIZ. Опишем их позже в этой главе. (Предостережение: следует избегать определения своих собственных идентификаторов NULL, EOF и BUFSIZ. Вообще говоря, пере­определять идентификаторы можно, но это влечет за собой ошибки прог­раммирования, поскольку текущее значение такого идентификатора трудно опре­делить.)

Другим файлом, который требуется при использовании функций стандартного вво­да-вывода, является библиотека этих функций, которая необходима на стадии за­грузки программы. Способ выборки функций из библиотеки зависит от используемой системы. При работе с системами типа UNIX библиотека может автоматически присо­единяться к Вашей программе. При работе на IBM PC Вам, возможно, придется ука­зывать имя библиотеки при вызове загрузчика. Мы уже показывали, как это делается при загрузке программ, в которых использовалась функция printf: в ответ на пригла­шение к вводу "Libraries [.LIB]:", выдаваемое загрузчиком IBM PC, вводилось имя библиотеки LC.LIB.

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

ТИПЫ ФУНКЦИЙ ФАЙЛОВОГО ВВОДА-ВЫВОДА

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

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

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

Библиотека файлового ввода-вывода состоит из функций, обеспечивающих вы­полнение перечисленных здесь операций. Все типы функций файлового ввода-вы­вода приведены в табл. 10.2.



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

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

ДОСТУП К ФАЙЛУ

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

Поскольку одновременно может иметься много открытых файлов, то функция fopen возвращает указатель на структуру FILE, соответствующую открываемому файлу. Этот указатель называется указателем файла; он должен быть сохранен для последующего использования в других функциях файлового ввода-вывода. Указатели файлов, показывающие на три устройства стандартного ввода-вывода (stdin, stdout и stderr), описаны в файле заголовка stdio.h. Для каждого другого файла программист должен сам определить указатель файла, в который будет помещено значение, возвращаемое функцией fopen, например:

FILE *fp; /* Указатель файла */

Затем программист должен указать вызов функции fopen. Аргументами функции fopen служат спецификация файла и режим доступа к файлу. Покажем типичный вызов функции fopen:

Аргументы функции fopen ,

if ((fp = fopen (file_specification, mode))= =NULL)

/* Обработка ошибки открытия файла */ }

Первый аргумент, file_specification, является указателем на строку (которая неред­ко является строковой константой), содержащей любое допустимое имя файла опе­рационной системы PC-DOS'. Формат имени файла имеет вид д:имя_файла.тип, где д: - имя дисковода, имя_файла - имя файла, а .тип - расширение имени файла. Если библиотека Вашего компилятора обеспечивает работу с областями файлов, то Вы можете включать в имя_файла также путь к файлу. Кроме того, Ваша операционная среда может иметь несколько специальных имен файлов. К ним относятся CON (console - консоль), СОМ1 (serial communication interface -последовательный порт ввода-вывода), PRN (printer - принтер), NUL (null device - фиктивное устройство) и некоторые другие.

Другой аргумент функции fopen, mode, также является указателем на строку. Эта строка задает желаемый доступ к файлу. Допускаются три режима, обозна­чаемые буквами r, w и a: чтение (read), запись (write) и дополнение (append). В табл. 10.3 описаны назначения этих режимов.

Таблица 10.3. Режимы открытия файла с помощью функции fopen



Некоторые реализации функции fopen обеспечивают дополнительные режимы модификации файлов. Их назначение показано в табл. 10.4.

Таблица 10.4. Режимы, обеспечивающие модификацию файла (чтение и запись)



При успешном вызове функция fopen возвращает непустой указатель типа FILE. При ошибке открытия файла возвращается пустое значение NULL Вы должны проверить значение, возвращаемое функцией fopen, чтобы убедиться в том, что файл открыт ус­пешно (см. приводимый далее пример). В некоторых реализациях языка Си предусмот­рена глобальная переменная целого типа errno. В нее автоматически помещается код ошибки, позволяющий получать дополнительную информацию о причинах, по которым файл не был открыт (см. разд. 10.7).

Указатель типа FILE, полученный в результате успешного вызова функции fopen, при любом последующем вызове функций ввода-вывода должен быть использован для идентификации файла, с которым они должны выполнить свои действия. Максимальное число файлов, которые могут быть одновременно открыты одной программой, определяется тремя факторами, зависящими от среды опе­рационной системы DOS. Ими служат:

1) общее число файлов, которые операционная система DOS позволяет откры­вать одновременно;

2) общее число файлов, которые операционная система DOS позволяет однов­ременно открывать данному процессу (исполняемой программе);

3) максимальное число структур FILE, заданное в файле заголовка stdio.h.

В операционной системе DOS версии 2.0 и более поздних версий, число из условия 1 (максимальное число открытых файлов, допускаемое операционной системой) может быть задано с помощью команды конфигурации FILES. Число из условия 2 полагается равным 12 в версии DOS 2.0 (в это число входят пять стандартных файлов: ввод, вывод, вывод сообщений об ошибках, вспомога­тельный и стандартный принтеры). Число из условия 3 определяется в файле за­головка stdio.h, поставляемом вместе с компилятором языка Си, и может быть изменено программистом. Более подробную информацию о том, как можно задать конфигурацию операционной системы DOS для Вашей системы, см. в руководстве по DOS, разд. 9 под названием "Configuring Your System" (задание конфигурации Вашей системы).

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

Использование функции fclose

8 include "stdio.h"

main() {

FILE *myfile;

if ((myfile = fopen("teat.dat","r")) = = NULL)

{

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

exit; } /* Работа с файлом */

.

.

.

/* Завершить работу с файлом */

fclose(myfile); } Программа 10.1

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

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

посимвольный ввод-вывод

Мы уже пользовались функцией (или макроопределением) посимвольного ввода данных, а именно getchar, которая обычно является частным случаем реализации более общих функций getc или fgetc. Во многих реализациях языка Си для опе­рационной среды UNIX getc и fgetc функционально идентичны, но getc реализо­вано как макроопределение, a fgetc - как настоящая функция. Некоторые библиотеки могут содержать одну или обе функции. Здесь обсудим функцию fgetc, но помните, что поведение функции getc аналогично.

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

«include "stdio.h" main()

FILE *fp; int ch;

/* Вызвать функцию fopen для установки указателя fp */ ch = fgetc(fp);

}

При каждом вызове функция fgetc будет выполнять чтение очередного символа файла. Чтение начинается с первого символа файла и прекращается, когда будет обнаружен его конец. В последнем случае функция fgetc возвращает значение EOF. Так как оно не должно совпадать с допустимыми ASCII-кодами, то нередко директивой #define оно определяется равным -1. По этой причине важно описы­вать переменную, в которую считывается символ (в нашем случае ch), как целую, а не символьную.

При работе под управлением операционной системы PC-DOS значение EOF воз­вращается, если на клавиатуре набрано CNTRL-Z.

Некоторые реализации функции fgetc могут возвращать или значение EOF, или другие значения при обнаружении неустранимых ошибок ввода (например, вы­званных неисправностью аппаратуры). Чтобы установить, что возвращение EOF действительно соответствует концу файла, надо использовать функцию feof. В результате вызова feof ( fp )

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

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

Чтобы записать отдельный символ в файл, воспользуйтесь вызовом fputc(ch, fp)

или

putc(ch, fp)

где ch представляет символ, который должен быть записан в файл, соответству­ющий указателю fp. Функция fputc просто последовательно записывает символы в файл. Опять-таки fputc и putc функционально идентичны, но fputc реализована как функция, a putc - как макроопределение.

Как уже упоминалось, функция getchar обычно реализуется как частный случай функции getc. Аналогично функция putchar может быть реализована как частный случай функции putc. Имена getchar и putchar нередко создаются с помощью директив препроцессора, включающих в себя указатели stdin и stdout типа FILE, показывающие на стандартные устройства ввода и вывода: #define getchar( ) getc(stdin)

#define putchar(ch) putc(ch, stdout)

Эти директивы включаются в файл заголовка stdio.h. Вот почему при использо­вании имен getchar и putchar такой файл надо включать в исходный модуль. Как и функции ввода данных, в операционной среде DOS некоторые функции вывода данных (например, fgetc и другие функции, которые будут обсуждаться далее), могут преобразовывать одни символы в другие, для того чтобы удовлетворялись соглашения, принятые в языке Си и операционной системе DOS. Преобразование символов обсуждается в разд. 10.5.

Еще одна полезная функция посимвольного ввода-вывода позволяет прог­раммисту "поместить обратно" символ, только что считанный с помощью функции fgetc, getc или getchar. В результате вызова ungetc (ch, fp)

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

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

Использование посимвольного ввода-вывода

«include "stdio.h"

/* Добавить Файл 1 к файлу 2 */

main(argc, argv)

int argc; /* Число аргументов в командной строке */

char *argv[]; /* Указатель на аргументы */

FILE *sp, *tp; /* Указатели на файл-приемник и

файл-источник */

char ch; /* Переписываемый символ */

if (argc != 3) {

printf("Формат команды: append источник приемник\n");

exit; }

if ((sр = fopen(argv[l],"r")) = = NULL) {

printf("Ошибка при открытии файла %s\n", argv[l]);

exit; }

if ((tp = fopen(argv[2],"a")) = = NULL) {

printf("Ошибка при открытии файла %s\n", argv[2]);

exit;

}

while ((ch = fgetc(sp)) != EOF)

{

fputc(ch, tp);

}

fclose(sp); fclose(tp);

}

Программа 10.2

Обратите внимание на цикл while. Символы по одному читаются из файла-источника и записываются в файл-приемник до тех пор, пока не будет обнаружен конец файла-источника. В этом случае функция fgetc (а также getchar) возвращает целое значение EOF (определенное в файле заголовка stdio.h). Заметьте, что при посимволь­ном вводе-выводе файл трактуется как непрерывный поток данных.

ФОРМАТИРОВАННЫЙ ВВОД-ВЫВОД

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

ФОРМАТИРОВАННЫЙ ВЫВОД

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

fprintf(fp, control_string_pointer, аргументы, ... )

(Заметьте, что функция printf просто является частным случаем функции fprintf: указателем типа FILE в ней является stdout.)

В данном примере переменная fp является попросту указателем файла, инициируемым функцией fopen.



Вторым аргументом функции fprintf является указатель на строку (обычно стро­ковая константа), которая состоит из текста и спецификаций преобразования. Текст выводится без изменений (за исключением управляющих символов, см. гл. 3). Для каждой спецификации преобразования значение очередного аргумента со­ответствующим образом преобразуется и выводится вместо спецификации (таким образом, число аргументов функции fprintf является переменным). Мы уже встре­чались с некоторыми простыми спецификациями преобразования, например %d -вывод десятичного числа, %х - вывод шестнадцатеричного числа, %s - вывод строки символов. Синтаксис спецификаций преобразования, используемых при вы­зове функций fprintf и printf, показан на диаграмме (рис. 10.0а), а примеры их использования приводятся в табл. 10.5.

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

ФОРМАТИРОВАННЫЙ ВВОД

Форматированные данные вводятся с помощью функции fscanf. Ее аргументы те же, что и у функции fprintf:

fscanf(fp, control_string_pointer, аргументы, ... )

scanf(control_string_pointer, аргументы, ... )

(функция scanf аналогична функции fscanf, но использует в качестве указателя файла stdin).

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

Интерпретация управляющей строки функции fscanf аналогична, но не идентична интерпретации управляющей строки функции fprintf. У этой функции, как и у функции printf, управляющая строка состоит из текста и спецификаций преобразования. Входящие в текст пробелы, символы табуляции или перехода на новую строку игнорируются. Другие символы (за исключением спецификаций пре­образования) образуют шаблон, с которым должны совпадать вводимые данные. Как и в случае функции fprintf, признаком начала спецификации преобразования служит символ %. Полный синтаксис спецификаций преобразования показан на рис. 10.0б.

Несколько примеров использования функции scanf приводится в табл. 10.6.










Обратите внимание на поле ввода junk 62. Спецификация преобразования %*s указывает, что первые четыре позиции ввода (соответствующие junk) должны игнорироваться. Учтите, что при вводе строки с помощью функции scanf заверша­ющий нулевой байт автоматически добавляется к ее концу (он обозначен через '\0' в приведенном в таблице примере).

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

построчный ввод-вывод

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

Построчный ввод выполняется функциями (или макроопределениями) fgets(char_pointer, size, fp)

и

gets(char_pointer, size)

которые считывают строку данных из файла, соответствующего указателю fp, в массив символов (или в область памяти с указанным адресом), заданный аргументом char_pointer. (Функция gets считывает данные из файла, соответствующего указателю stdin.) Функция fgets добавляет нулевой байт к концу строки после считывания ее в память. Символы считываются из файла до тех пор, пока не будет выполнено одно из следующих условий:

1) обнаружен конец строки;

2) обнаружен конец файла;

3) число символов в считываемой строке равно size. Чтобы избежать перепол­нения области памяти, в которую считывается строка, в нее должно быть поме­щено не более size-1 символов (чтобы хватило места и для нулевого байта). Если длина считываемой строки превышает size, то считывание остальных символов бу­дет продолжено при следующем вызове функции fgets.

Функция fgets возвращает значение, которое равно либо исходному значению аргумента char_pointer (указателя на область памяти), либо значению EOF, если обнаружен конец файла.

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

Построчный вывод выполняется функциями fputs(char_pointer, fp)

И

puts(char_pointer)

которые передают данные из массива символов с адресом char_pointer в файл, со­ответствующий указателю fp, до тех пор, пока не будет обнаружен завершающий строку нулевой байт.

Функция fputs возвращает отрицательное значение, обычно EOF, если обнару­жена ошибка при выводе данных. Значение, которое возвращается после успеш­ного вызова функции, зависит от реализации, но обычно отличается от EOF.

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

Программа 10.3 выполняет слияние файлов, но на этот раз с помощью построч­ного ввода-вывода:

Использование построчного ввода-вывода

«include "stdio.h"

/*' Добавить файл 1 к файлу 2 */

main(argc, argv)

int argc; /* Число аргументов в командной строке */

char *argv[]; /* Указатель на аргументы */

{

FILE .-, *ар, *tp; /* Указатели на файл-приемник и

Файл-источник */

char line[81]; /* Переписываемая строка */

if (argc != 3)

{

printf("Формат команды: append источник приемник\n");

exit;

}

if ((sp = fopen(argv[l],"r")) = =. NULL) {

printf("Ошибка при открытии файла %s\n", argv[1]);

exit;

}

if ((tp = fopen(argv[2],"a")) = = NULL)

{

printf("Ошибка при открытии файла %a\n", argv[2]); exit;

while ( fgets(line, slzeof (line), sp)) != EOF)

{

fputs(line, tp);

}

fclose(sp); fclose(tp);

}

Программа 10.3

Вместо считывания по одному символу за прием эта программа считывает пол­ную строку (до 80 символов). Имейте в виду, что функция fputs записывает в файл символы из строки line до тех пор, пока не обнаружит нулевой байт (поме­щенный в нее функцией fgets).

ВВОД-ВЫВОД ЗАПИСЕЙ

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

Например, функция

fred(pointer, size, no_records, fp)

будет считывать из заданного файла записи фиксированной длины, число байтов в которых равно значению size. Количество считываемых записей определяется це­лым значением no_records. Данные считываются из файла, соответствующего ука­зателю fp, в область памяти с адресом, указанным в аргументе pointer. Например, следующий фрагмент

Использование ввода-вывода записей #include "stdio.h" #include "stock.h" main( )

struct STOCK_INFO stock-rec, /* Запись о сделке */ FILE *tp; /* Файл наличных акций */

int n;

fp = fopen("stock.dat","r");

n = fread(&stock_rec, sizeof(stock_rec), 1, fp);

}

считает одну запись (sizeof (stock_rec) байтов) в структуру stock_rec. Если аргумент 1 изменить на 2, то в память будут считаны две записи (тогда потребуется изменить определение структуры на массив структур).

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

Функция вывода

fwrite(pointer, size, no_records, fp);

записывает в файл несколько записей, число которых определяется значением no_records. Записываемые данные берутся из области памяти с адресом, равным значению указателя pointer. Длина каждой записи (в байтах) равна значению size. Этот аргумент часто кодируется как sizeof(*pointer). При успешном вызове функция fwrite возвращает значение, равное числу переданных записей. При ошибке записи она возвращает нуль.

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

ВНУТРЕННЕЕ ПРЕОБРАЗОВАНИЕ ДАННЫХ

Внутренние преобразования данных одного типа в данные другого типа можно достаточно просто выполнять с помощью функций sprintf и sscanf. Управляющие строки и спецификации преобразований для этих функций те же, что и для функций fprintf и fscanf; при этом выполняются аналогичные действия, но вместо указателя на файл используется указатель на строковую переменную:

sprintf(pointer, control_string_pointer, аргументы, ... )

и

sscanf(pointer, control_string_pointer, аргументы, ... )

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

Использование функции sprintf main( )

char string[10]; float value - 3.12;

sprintf(string, %f, value);

преобразует в строку символов двоичное число с плавающей точкой, содержащееся в переменной value, и поместит эти символы в массив string. При вызове функции sscanf

Использование функции sscanf char string[10] - "3.12"; main( )

float value; sscanf(string, %f, &value);

будет выполнена обратная операцию - символы "3.12" преобразуются в двоичное число с плавающей точкой, которое будет помещено по адресу &value.

Если Вас интересует синтаксис управляющих строк для функций sprintf и sscanf, то обратитесь к диаграммам, описывающим синтаксис управляющих строк для функций printf и scanf.
  1   2   3



Похожие:

Ввод, вывод и стандартная библиотека функций ввода-вывода icon№ п/п Термин
Потоковый ввод-вывод, направленный не на одно из стандартных устройств ввода-вывода, а в текстовый или двоичный файл
Ввод, вывод и стандартная библиотека функций ввода-вывода iconЛекция 02 Прямой ввод-вывод: организация и функции Вывод на дисплей. Часть Содержание: 02. 00. Аннотация. 02. 01. Вывод символов на экран 02. 02. Режимы работы дисплея
«Среднеуровневый» ввод-вывод возможен только на консоль, работающую в «текстовом режиме», с помощью «базовых» прерываний ms-dos и...
Ввод, вывод и стандартная библиотека функций ввода-вывода iconЛекция 08 Буферизированный (потоковый) ввод-вывод Часть III. Содержание 08. 00. Аннотация
На данной лекции Вы познакомитесь с «потоковым» вводом-выводом данных, и подробно рассмотрите операцию вывода в стандартные потоки...
Ввод, вывод и стандартная библиотека функций ввода-вывода iconЛекция 07 Буферизированный (потоковый) ввод-вывод Часть II содержание 07. 00. Аннотация
...
Ввод, вывод и стандартная библиотека функций ввода-вывода iconЛекция 09 Ввод-вывод с использованием Winapi содержание: 09. 00. Аннотация
На этой лекции Вы познакомитесь с файловыми операциями ввода-вывода с использованием api windows, а также научитесь программировать...
Ввод, вывод и стандартная библиотека функций ввода-вывода iconЛекция 01 Классификация ввода-вывода Содержание: 01. 00. Аннотация
Без них невозможно никакое общение между эвм, и между ЭВМ и человеком. Однако в реализации этих операторов существуют большие различия,...
Ввод, вывод и стандартная библиотека функций ввода-вывода iconЛекция 06 Буферизированный (потоковый) ввод-вывод Содержание 06. 00. Аннотация
...
Ввод, вывод и стандартная библиотека функций ввода-вывода iconПериферийных устройств
Периферийные устройства делятся на устройства ввода и устройства вывода. Устройства ввода преобразуют информацию в форму понятную...
Ввод, вывод и стандартная библиотека функций ввода-вывода icon№ п/п Термин
Прямоугольная область экрана, созданная приложением, которой перенаправляются действия от клавиатуры и мыши, и в которое перенаправляется...
Ввод, вывод и стандартная библиотека функций ввода-вывода iconЛекция 05 Ввод с клавиатуры Содержание: 05. 00. Аннотация
«на среднем уровне» позволяет вводить и выводить текстовые символы в файл, на консоль, модем, удалённый терминал. При этом в ms-dos...
Ввод, вывод и стандартная библиотека функций ввода-вывода iconСтандартная клавиатура ibm pc имеет несколько групп клавиш: Управляющие клавиши
Клавиши ввода (алфавитно-цифровые) и знаковые клавиши (с латинскими и русскими буквами, цифрами, знаками пунктуации, математическими...
Разместите кнопку на своём сайте:
Документы


База данных защищена авторским правом ©podelise.ru 2000-2014
При копировании материала обязательно указание активной ссылки открытой для индексации.
обратиться к администрации
Документы

Разработка сайта — Веб студия Адаманов