Лекции, страница 10
Описание файла
PDF-файл из архива "Лекции", который расположен в категории "". Всё это находится в предмете "основы конструкторско-технологической информатики (окти)" из 2 семестр, которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 10 страницы из PDF
Отличие от функции fgets втом, что не указывается размер массива line. В результате, подав на вход функции getsочень длинную строку, можно добиться переполнения массива и стереть или подменитьучасток памяти, используемый программой. Если программа имеет привилегиисуперпользователя, то применение в ней функции gets открывает путь к взлому системы,который использовался хакерами. Поэтому в настоящее время функция gets считаетсяопасной и применение ее не рекомендовано. Вместо gets следует использовать fgets стретьим аргументом stdin.При выполнении файловых операций исполняющая система поддерживаетуказатель текущей позиции в файле. При чтении или записи n байтов указатель текущейпозиции увеличивается на n; таким образом, чтение или запись происходятпоследовательно. Библиотека ввода-вывода Си предоставляет, однако, возможностьнарушать эту последовательность путем позиционирования в произвольную точку файла.Для этого используется стандартная функция fseek с прототипомint fseek(FILE *f, long offset, int whence);Первый аргумент f функции определяет файл, для которого производится операцияпозиционирования.
Второй аргумент offset задает смещение в байтах, оно может быть какположительным, так и отрицательным. Третий аргумент whence указывает, откуда33отсчитывать смещение. Он может принимать одно из трех значений, заданных как целыеконстанты в стандартном заголовочном файле "stdio.h":SEEK_CURSEEK_SETSEEK_ENDсмещение отсчитывается от текущей позициисмещение отсчитывается от начала файласмещение отсчитывается от конца файлаНапример:fseek(f, 0, SEEK_SET);устанавливает текущую позицию в начало файла. Фрагментfseek(f, -4, SEEK_END);устанавливает текущую позицию в четырех байтах перед концом файла. Наконец,фрагментfseek(f, 12, SEEK_CUR);продвигает текущую позицию на 12 байтов вперед.Отметим, что смещение может быть положительным даже при использовании константыSEEK_END (т.е.
при позиционировании относительно конца файла): в этом случае приследующей записи размер файла соответственно увеличивается.Функция возвращает нулевое значение в случае успеха и отрицательное значениеEOF (равное -1) при неудаче - например, если указанное смещение некорректно призаданной операции или если файл или поток не позволяет выполнять прямоепозиционирование.Узнать текущую позицию относительно начала файла можно с помощью функцииftell с прототипомlong ftell(FILE *f);Функция ftell возвращает текущую позицию (неотрицательное значение) в случае успехаили отрицательное значение -1 при неудаче (например, если файл не разрешает прямоепозиционирование).Наконец, узнать, находится ли текущая позиция в конце файла, можно с помощьюфункции feof с прототипомint feof(FILE *f);Она возвращает ненулевое значение (т.е.
истину), если конец файла достигнут, и нулевоезначение (т.е. ложь) в противном случае. Например, в следующем фрагменте в циклепроверяется, достигнут ли конец файла, и, если нет, считывается очередной байт:FILE *f;. . .while (!feof(f)) {int c = fgetc(f);. . .}////////цикл пока не конец файла| прочесть очередной байт| . . .конец циклаРабота с текстамиСтандартная библиотека Си предоставляет набор функций для работы с текстами. К сожалению,большая часть из них ориентирована на представление символов в виде одного байта (во время разработкиязыка Си кодировка Unicode, в которой на символ отводится два байта, еще не существовала). Функцииможно разделить на две группы:1.2.функции, определяющие тип символа, - является ли он буквой, цифрой, пробелом, знакомпрепинания и т.п. Это функции описаны в стандартном заголовочном файле "ctype.h".
Увы,функции, касающиеся букв, работают только для латинского алфавита;функции для работы с текстовыми строками. Строкой в Си считается последовательность байтов,ограниченная в конце нулевым байтом. Функции работы со строками описаны в стандартномзаголовочном файле "string.h".Определение типов символов34Библиотека Си предоставляет следующие функции для определения типасимволов, описанные в стандартном заголовочном файле "ctype.h":int isdigit(int c);int isalpha(int c);int isspace(int c);int ispunkt(int c);int isupper(int c);int islower(int c);int toupper(int c);int tolower(int c);символ c - цифра;c - латинская буква;c - пробел, перевод строки и т.п.;c - знак препинания;c - прописная латинская буква;c - строчная латинская буква;если c -- лат. буква, то преобразовать c к прописной букве;если c -- лат.
буква, то преобразовать c к строчной букве.Функции, начинающиеся с префикса is, возвращают ненулевое значение (т.е.истину), если символ с кодом c принадлежит указанному классу, и нулевое значение(ложь) в противном случае. Функции toupper и tolower преобразуют латинские буквы кверхнему или нижнему регистру, на остальных символах они действуют тождественно.В качестве примера использования функции isspace модифицируем программу "wc.cpp",подсчитывающую число строк и символов в текстовом файле.
Добавим в нее подсчетслов. Будем считать словами любые связные группы символов, разделенные пробелами,табуляциями или разделителями строк.//// Файл "wc2.cpp"// Подсчет числа символов, слов и строк в текстовом файле//#include <stdio.h> // Описания функций ввода-вывода#include <ctype.h> // Описания типов символовint main() {char fileName[256]; // Путь к файлуFILE *f;// Структура, описывающая файлint c;// Код введенного символаint numChars = 0;// Суммарное число символов := 0int numLines = 0;// Суммарное число строк := 0int numWords = 0;// Суммарное число слов := 0bool readingWord = false; // Читаем слово := falseprintf("Введите имя файла: ");scanf("%s", fileName);f = fopen(fileName, "rb"); // Открываем файлif (f == 0) { // При ошибке открытия файла// Напечатать сообщение об ошибкеperror("Не могу открыть файл для чтения");return 1; // закончить работу программы с кодом 1}while ((c = fgetc(f)) != EOF) { // Читаем символ// Цикл продолжается, пока c != -1 (конец файла)++numChars; // Увеличиваем число символов// Подсчитываем число символов перевода строкиif (c == '\n') {++numLines; // Увеличиваем число строк}// Подсчитываем число словif (!isspace(c)) {// если c не пробелif (!readingWord) { // если не читаем слово++numWords;//увеличить число словreadingWord = true; // читаем слово:=true35}}// конец если} else {// иначеreadingWord = false;// читаем слово:=false}// конец еслиfclose(f);// Печатаем результатprintf("Число символов в файле = %d\n", numChars);printf("Число слов = %d\n", numWords);printf("Число строк = %d\n", numLines);}return 0; // Возвращаем код успешного завершенияПример выполнения программы wc2 в применении к собственному тексту, записанному вфайле "wc2.cpp":Введите имя файла: wc2.cppЧисло символов в файле = 1998Число слов = 260Число строк = 57Работа с текстовыми строкамиСтандартная библиотека Си предоставляет средства вычисления длины строки,копирования, сравнения, соединения (конкатенации) строк, поиска вхождений однойстроки в другую.
Функции описаны в стандартном заголовочном файле "string.h".Прототипы наиболее часто используемых функций приведены ниже.Определение длины строки:size_t strlen(const char *s); //длина строки;Копирование строк:char *strcpy(char *dst, const char *src); /*копировать строку src в строкуdst;*/char *strncpy(char *dst, const char *src, size_t maxlen); /*копировать строкуsrc в dst, не более maxlen символов;*/char *strcat(char *dst, const char *src); /*копировать строку src в конец dst(конкатенация строк).*/Работа с произвольными массивами байтов:void *memmove(void *dst, const void *src, size_t len); /*копировать областьпамяти с адресом src размером len байтов в область памяти с адресом dst;*/void *memset(void *dst, int value, size_t len); /*записать значение value вкаждый из len байтов, начиная с адреса dst.*/Сравнение строк:int strcmp(const char *s1, const char *s2); /*лексикографическое сравнениестрок s1 и s2.
Результат нулевой, если строки равны, отрицательный, еслипервая строка меньше второй, и положительный, если первая строка большевторой;*/int strncmp(const char *s1, const char *s2, size_t maxlen); /*сравнение строкs1 и s2, сравнивается не более maxlen символов; */int memcmp(const void *m1, const void *m2, size_t len);/* сравнение областейпамяти с адресами m1 и m2 размером len каждая. */Поиск:char *strchr(const char *s, int c); /*найти первое вхождение символа c встроку s. Функция возвращает указатель на найденный символ или ноль в случаенеудачи;*/char *strstr(const char *s1, const char *s2); /*найти первое вхождение строкиs2 в строку s1. Функция возвращает указатель на найденную подстроку в s1,равную строке s2, или ноль в случае неудачи.*/Функции библиотеки ввода-выводаФункции для работы с файлами36fopen – открывает поток, связанный с файлом filename и типом доступа type.FILE *fopen(char *filename, char *type);fclose – закрывает поток stream.int fclose(FILE *stream);fcloseall – закрывает все открытые потоки.int fcloseall( void );remove – удаляет файл с именем filename.int remove( char *filename );rename – переименовывает файл oldname в файл newname.int rename(char *oldname, char *newname);ftell – возвращает положение указателя текущей позиции файла, связанного спотоком stream.