Лекции, страница 7
Описание файла
PDF-файл из архива "Лекции", который расположен в категории "". Всё это находится в предмете "основы конструкторско-технологической информатики (окти)" из 2 семестр, которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 7 страницы из PDF
Тогда функция может записать любую информацию по переданным адресам. В Ситаким образом реализуются выходные и входно-выходные параметры функций.Описания прототипов функций обычно выносятся в заголовочные файлы, см. раздел 3.1.Для коротких программ, которые помещаются в одном файле, описания прототиповрасполагают в начале программы. Рассмотрим пример такой короткой программы.21Пример: вычисление наибольшего общего делителяПрограмма вводит с клавиатуры терминала два целых числа, затем вычисляет и печатаетих наибольший общий делитель.
Непосредственно вычисление наибольшего общего делителяреализовано в виде отдельной функцииint gcd(int x, int y);(gcd - от слов greatest common divizor). Основная функция main лишь вводит исходные данные,вызывает функцию gcd и печатает ответ. Описание прототипа функции gcd располагается вначале текста программы, затем следует функция main и в конце - реализация функции gcd.Приведем полный текст программы:#include <stdio.h> // Описания стандартного ввода-выводаint gcd(int x, int y); // Описание прототипа функцииint main() {int x, y, d;printf("Введите два числа:\n");scanf("%d%d", &x, &y);d = gcd(x, y);printf("НОД = %d\n", d);return 0;}int gcd(int x, int y) { // Реализация функции gcdwhile (y != 0) {// Инвариант: НОД(x, y) не меняетсяint r = x % y; // Заменяем пару (x, y) наx = y;// пару (y, r), где r -y = r;// остаток от деления x на y}// Утверждение: y == 0return x;// НОД(x, 0) = x}ЗАДАНИЯ1.
Дана строка символов S. Напечатайте все входящие в эту строку заглавные латинскиебуквы 'A', ... , 'Z' по одному pазу в алфавитном порядке с указанием числа вхожденийкаждой буквы в строку. Проверку на признак заглавной буквы и подсчет количествавхождений в строку оформить в виде функции.2. Напишите пpогpамму, содержащую функцию удаления из вектора элемента пеpедзаданным.
Заданный элемент определяется по его порядковому номеру.3. Пусть в векторе вещественных чисел содержатся результаты измерения некоторойвеличины x в нескольких опытах. Вычислите среднее значение величины x по формулеn −1M[X]= ∑ xi /n,гдеn–количествоизмерений,идисперсиюпоi =0n −12формуле:D[X]= ∑ ( M [ X ] − xi ) /n. Вычисление среднего арифметического M[X] иi =0дисперсии D[X] организовать в виде отдельных функций.22Работа с файламиСтандартная библиотека Си содержит набор функций для работы с файлами.
Этифункции описаны в стандарте ANSI. Отметим, что файловый ввод-вывод не являетсячастью языка Си, и ANSI-функции - не единственное средство ввода-вывода. Так, воперационной системе Unix более популярен другой набор функций ввода-вывода,который можно использовать не только для работы с файлами, но и для обмена по сети.Открытие файла: функция fopenДля доступа к файлу применяется тип данных FILE. Это структурный тип, имякоторого задано с помощью оператора typedef в стандартном заголовочном файле"stdio.h". Программисту не нужно знать, как устроена структура типа файл: ее устройствоможет быть системно зависимым, поэтому в целях переносимости программ обращатьсяявно к полям струтуры FILE запрещено.
Тип данных "указатель на структуру FILEиспользуется в программах как черный ящик: функция открытия файла возвращает этотуказатель в случае успеха, и в дальнейшем все файловые функции применяют его длядоступа к файлу.Прототип функции открытия файла выглядит следующим образом:FILE *fopen(const char *path, const char *mode);Здесь path - путь к файлу (например, имя файла или абсолютный путь к файлу), mode режим открытия файла. Строка mode может содержать несколько букв. Буква "r" (от словаread) означает, что файл открывается для чтения (файл должен существовать). Буква "w"(от слова write) означает запись в файл, при этом старое содержимое файла теряется, а вслучае отсутствия файла он создается.
Буква "a" (от слова append) означает запись в конецсуществующего файла или создание нового файла, если файл не существует.В некоторых операционных системах имеются различия в работе с текстовыми ибинарными файлами (к таким системам относятся MS DOS и MS Windows; в системе Unixразличий между текстовыми и бинарными файлами нет). В таких системах при открытиибинарного файла к строке mode следует добавлять букву "b" (от слова binary), а приоткрытии текстового файла -- букву "t" (от слова text).
Кроме того, при открытии можноразрешить выполнять как операции чтения, так и записи; для этого используется символ +(плюс). Порядок букв в строке mode следующий: сначала идет одна из букв "r", "w", "a",затем в произвольном порядке могут идти символы "b", "t", "+". Буквы "b" и "t" можноиспользовать, даже если в операционной системе нет различий между бинарными итекстовыми файлами, в этом случае они просто игнорируются.Значения символов в строке mode сведены в следующую таблицу:rwatb+Открыть существующий файл на чтениеОткрыть файл на запись. Старое содержимое файла теряется, в случае отсутствия файла онсоздаётся.Открыть файл на запись.
Если файл существует, то запись производится в его конец.Открыть текстовый файл.Открыть бинарный файл.Разрешить и чтение, и запись.Несколько примеров открытия файлов:FILE *f, *g, *h;. . .// 1. Открыть текстовый файл "abcd.txt" для чтенияf = fopen("abcd.txt", "rt");// 2. Открыть бинарный файл "c:\Windows\Temp\tmp.dat"// для чтения и записиg = fopen("c:/Windows/Temp/tmp.dat", "wb+");23// 3. Открыть текстовый файл "c:\Windows\Temp\abcd.log"// для дописывания в конец файлаh = fopen("c:\\Windows\\Temp\\abcd.log", "at");Обратите внимание, что во втором случае мы используем обычную косую черту / дляразделения директорий, хотя в системах MS DOS и MS Windows для этого принятоиспользовать обратную косую черту \. Дело в том, что в операционной системе Unix и вязыке Си, который является для нее родным, символ \ используется в качествеэкранирующего символа, т.е. для защиты следующего за ним символа от интерпретациикак специального.
Поэтому во всех строковых константах Си обратную косую черту надоповторять дважды, как это и сделано в третьем примере. Впрочем, стандартнаябиблиотека Си позволяет в именах файлов использовать нормальную косую черту вместообратной; эта возможность была использована во втором примере.В случае удачи функция fopen открытия файла возвращает ненулевой указатель наструктуру типа FILE, описывающую параметры открытого файла. Этот указатель надозатем использовать во всех файловых операциях.
В случае неудачи (например, припопытке открыть на чтение несуществующий файл) возвращается нулевой указатель. Приэтом глобальная системная переменная errno, описанная в стандартном заголовочномфайле "errno.h, содержит численный код ошибки. В случае неудачи при открытии файлаэтот код можно распечатать, чтобы получить дополнительную информацию:#include <stdio.h>#include <errno.h>. . .FILE *f = fopen("filnam.txt", "rt");if (f == NULL) {printf("Ошибка открытия файла с кодом %d\n",errno);. . .}В приведенном выше примере при открытии файла функция fopen в случае ошибкивозвращает нулевой указатель на структуру FILE. Чтобы проверить, произошла лиошибка, следует сравнить возвращенное значение с нулевым указателем.
Для наглядностистандартный заголовочный файл "stdio.h" определяет символическую константу NULLкак нулевой указатель на тип void:#define NULL ((void *) 0)Сделано это вроде бы с благой целью: чтобы отличить число ноль от нулевого указателя.При этом язык Си, в котором контроль ошибок осуществляется недостаточно строго,позволяет сравнивать указатель общего типа void * с любым другим указателем. Междутем,в Си вместо константы NULL всегда можно использовать просто 0, и вряд ли от этогопрограмма становится менее понятной.Диагностика ошибок: функция perrorИспользовать переменную errno для печати кода ошибки не очень удобно,поскольку необходимо иметь под рукой таблицу возможных кодов ошибок и их значений.В стандартной библиотеке Си существует более удобная функция perror, которая печатаетсистемное сообщение о последней ошибке вместо ее кода. Печать производится наанглийском языке, но есть возможность добавить к системному сообщению любой текст,который указывается в качестве единственного аргумента функции perror.
Например,предыдущий фрагмент переписывается следующим образом:24#include <stdio.h>. . .FILE *f = fopen("filnam.txt", "rt");if (f == 0) {perror("Не могу открыть файл на чтение");. . .}Функция perror печатает сначала пользовательское сообщение об ошибке, затемпосле двоеточия системное сообщение. Например, при выполнении приведенногофрагмента в случае ошибки из-за отсутствия файла будет напечатаноНе могу открыть файл на чтение: No such file or directoryФункции бинарного чтения и записи fread и fwriteПосле того как файл открыт, можно читать информацию из файла или записывать информацию вфайл.
Рассмотрим сначала функции бинарного чтения и записи fread и fwrite. Они называются бинарнымипотому, что не выполняют никакого преобразования информации при вводе или выводе (с однимнебольшим исключением при работе с текстовыми файлами, которое будет рассмотрено ниже): информацияхранится в файле как последовательность байтов ровно в том виде, в котором она хранится в памятикомпьютера.Функция чтения fread имеет следующий прототип:size_t fread(char *buffer,size_t elemSize,size_t numElems,FILE *f);////////Массив для чтения данныхРазмер одного элементаЧисло элементов для чтенияУказатель на структуру FILEЗдесь size_t определен как беззнаковый целый тип в системных заголовочных файлах.Функция пытается прочесть numElems элементов из файла, который задается указателем fна структуру FILE, размер каждого элемента равен elemSize.
Функция возвращаетреальное число прочитанных элементов, которое может быть меньше, чем numElems, вслучае конца файла или ошибки чтения. Указатель f должен быть возвращен функциейfopen в результате успешного открытия файла. Пример использования функции fread:FILE *f;double buff[100];size_t res;f = fopen("tmp.dat", "rb"); // Открываем файлif (f == 0) { // При ошибке открытия файла// Напечатать сообщение об ошибкеperror("Не могу открыть файл для чтения");exit(1); // завершить работу с кодом 1}// Пытаемся прочесть 100 вещественных чисел из файлаres = fread(buff, sizeof(double), 100, f);// res равно реальному количеству прочитанных чиселВ этом примере файл "tmp.dat" открывается на чтение как бинарный, из него читается 100вещественных чисел размером 8 байт каждое.
Функция fread возвращает реальноеколичество прочитанных чисел, которое меньше или равно, чем 100. Функция fread читаетинформацию в виде потока байтов и в неизменном виде помещает ее в память. Следуетразличать текстовое представление чисел и их бинарное представление. В приведенномвыше примере числа в файле должны быть записаны в бинарном виде, а не в виде текста.Для текстового ввода чисел надо использовать функции ввода по формату, которые будутрассмотрены ниже.Открытие файла как текстового с помощью функции fopen, например:FILE *f = fopen("tmp.dat", "rt");вовсе не означает, что числа при вводе с помощью функции fopen будутпреобразовываться из текстовой формы в бинарную.
Из этого следует только то, что в25операционных системах, в которых строки текстовых файлов разделяются парамисимволами "\r\n" (они имеют названия CR и LF - возврат каретки и продергивание бумаги,Carriage Return и Line Feed), при вводе такие пары символов заменяются на один символ"\n" (продергивание бумаги). Обратно, при выводе символ "\n" заменяется на пару "\r\n".Такими операционными системами являются MS DOS и MS Windows. В системе Unixстроки разделяются одним символом "\n" (отсюда проистекает обозначение "\n", котороерасшифровывается как new line).