Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.209.121] |
|
Страницы: (4) [1] 2 3 ... Последняя » все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Так как справочной литературы по стандартной библиотеке С не так уж и много, я создал небольшое подобие
помощи по главной библиотеке великого и могучего. Когда я отправил этот пост, будет готова статья по string.h и статья по использованию файловых функций. Также вы сможете ознакомиться с возможностями по оптимизации и с узкими местами приведенных функций. Обсуждаем первую статью! Об очепятках и неточностях можно писать прямо в этом топике! Если сочту нужным, то подправлю. Когда вся серия статей будет готова, отправлю в FAQ. Стандартная библиотека С. Функции библиотеки string.h Для обработки строк в программах, написанных на С, применяют билиотеку string.h. В нее входит достаточно большое количество функций. Перед этой библиотеки использованием следует ее подключить: #include <string.h> Создание строк Для создания (не в памяти, аих инициализации) строк применяют функции strcpy и strcat, а также несколько их аналогов. Перед использованием функции strcpy (STRing CoPY) следует проверить, выделена ли память под обе строки. Объявление функции копирования строк: char *strcpy(char *dest, const char *src); wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); char *strncpy(char *dest, const char *src, size_t maxlen); wchar_t *wcsncpy(wchar_t *dest, const wchar_t *src, size_t maxlen); char far * far _fstrncpy(char far *dest, const char far *src, size_t maxlen) Общее их значение таково: строка, находящаяся в src помещается в dest. Если Вы хотите ограничить количество копируемых символов (это бывает полезно, когда длина строки ограничена) следует использовать функцию strncpy. Функции возвращают указатель на полученную строку. Для того, чтобы прибавить к строке другую, программисты используют функцию strcat (STRing conCATenate). Объявление функции добавления строк: char *strcat(char *dest, const char *src); wchar_t *wcscat(wchar_t *dest, const wchar_t *src); char __far * _fstrcat(char __far *dest, const char __far *src); Эти функции добавляют строку src в конец строки dest. За счет того, что функции возвращают указатель на полученную строку, имеется возможность использовать вложенные вызовы. Премер использования функций создания строк. #include <alloc.h> //или #include <stdlib.h> #include <string.h> #include <stdio.h> int main() { char *s, *s1, *s2; s1 = strdup(" text0 "); s2 = strdup(" text1 "); s = malloc(128); *s="\0"; //Я инициализирую строки так это - намного быстрее вызовов strcpy strcat(s,s1); //Функция strcat strcat(s,s2); printf("%s\n", s); free(s1); free(s2); free(s); return 0; } Вы увидите на экране " text0 text1 text2 ". Здесь мы познакомились с функцией strdup (STRing DUPclicate). Это аналог функции strcpy, но помимо копирования строки, она выделяет память и возвращает указатель на нее. Ее вызов эквивалентен вызовам malloc и strcpy, поэтому Про strdup надо написать следующее: блок памяти, выделенный для размещения дубликата строки, необходимо вручную удалять при помощи функции free. В string.h она объявлена так: char *strdup(const char *s); wchar_t *_wcsdup(const wchar_t *s); char far *_fstrdup(const char far *s) С использованием этих функций связано много подводных камней. Например, иногда под одну из строк не выделена память, это распространенная ошибка. Сравнее строк и поиск подстрок. Сравнее строк представлено в С функциями strcmp, strncmp, strncmpi (strnicmp) , strcmpi (stricmp). Следует заметить, что функции strcmpi и stricmp, а также strncmpi и strnicmp идентичны. Самый простой способ сравнить две строки, использовать функцию strcmp (STRing CoMPare). Эта функция сравнивает две строки без учета регистра. Протитипы функций выглядят так: int strcmp(const char *s1, const char *s2); int _fstrcmp(const far char *s1, const far char *s2); int wcscmp(const wchar_t *s1, const wchar_t *s2); Для всех функций сравнения существует единое правило возращаемого значения: Результат Возвращаемое значение Строка s1 меньше строки s2 <0 Строка s1 равна строке s2 =0 Строка s1 больше строки s2 >0 Для того, чтобы сравнивать строки c учетом регистра, следует использовать функцию stricmp или strcmpi. Следует сделать важную оговорку: регистр определяется только для латиницы. Объявлена эта функция так: int stricmp(const char *s1, const char *s2); int _wcsicmp(const wchar_t *s1, const wchar_t *s2); int far _fstricmp(const char far *s1, const char far *s2) int strcmpi(const char *s1, const char *s2); Я не оговариваю возвращаемые значения этих функций, так как они такие же, как и для strcmp. Если вы хотите ограничить количество сравниваемых символов, используйте функции с содержащие в названии букву 'n': int strncmp(const char *s1, const char *s2, size_t maxlen); int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t maxlen); int far _fstrncmp(const char far *s1, const char far *s2, size_t maxlen); /* Без учета регистра */ int strncmpi(const char *s1, const char *s2, size_t n); int wcsncmpi(const wchar_t *s1, const wchar_t *s2, size_t n); Для того, чтобы найти какую-то подстроку в данной строке, необходимо использовать функции strstr (общая) и strchr (для символов), strspn, strpbrk. Для того, чтобы найти подстроку, программисты обычно используют функцию strstr (STRing in STRing). Объявлена она так: char *strstr(const char *s1, const char *s2); char far * far _fstrstr(const char far *s1, const char far*s2); Главное замечание состоит в том, что эти прототипы верны только для С, в С++ первый параметр объявляется без спецификатора const. Возвращает эта функция указатель на первое вхождение s2 в s1 или NULL, если s2 не содержится в s1. Если вам необходимо найти не подстроку, а один из символов строки, используйте функцию strchr (STRing includes CHaR). Ее прототип: /* Для С */ char *strchr(const char *s, int c); char far * far _fstrchr(const char far *s, int c); //Для С++ const char *strchr(const char *s, int c); //или char *strchr( char *s, int c); wchar_t *wcschr(const wchar_t *s, int c); const char far * far _fstrchr(const char far *s, int c); char far * far _fstrchr( char far *s, int c); Эта функция возвращает указатель на первое вхождение символа c в s. Для нахождения последнего вхождения этого символа, применяйте strrchr. Если Вам необходимо найти один из множества символов, используйте функцию strpbrk. Как и у strchr, для С и С++ прототип разный. /* C */ char *strpbrk(const char *s1, const char *s2); char far *far _fstrpbrk(const char far *s1, const char far*s2) //C++ const char *strpbrk(const char *s1, const char *s2); char *strpbrk(char *s1, const char *s2); const char far *far _fstrpbrk(const char far *s1, const char far *s2); char far * far _fstrpbrk(char far *s1, const char far *s2); wchar_t * wcspbrk(const wchar_t *s1, const wchar_t *s2); Возвращаемым значением является указатель на первое вхождение одного из символов из s2 в строку s1. Функция strspn объявлена так: size_t strspn(const char *s1, const char *s2); size_t wcsspn(const wchar_t *s1, const wchar_t *s2); size_t far _fstrspn(const char far *s1, const char far *s2); Эта функция возвращает число первых символов, строки s1, которые входят в множество символов s1 (последовательность безразлична). Функция strcspn возвращает индекс первого символа в s1, который принадлежит множеству символов s2. size_t strcspn(const char *s1, const char *s2); size_t wcscspn(const wchar_t *s1, const wchar_t *s2); size_t far *far _fstrcspn(const char far *s1, const char far *s2); Общие замечания. Прочие функции Для того, чтобы вычислить длину строки, следует использовать функцию strlen (STRing LENgth) вместо оператора sizeof. size_t strlen(const char *s); size_t wcslen(const wchar_t *s); size_t far _fstrlen(const char far *s) Возвращает эта функция длину строки s. Иногда функцию strlen используют в циклах, в качестве ограничивающего аргумента. Если Вы хотите оптимизировать свой код, Вам необходимо заранее сосчитать длину строки, а затем использовать полученную переменную в цикле. Это позволит Вам сэкономить время на вызов функции и подсчет длины. Если длина не статична, можно менять полученную переменную в цикле. Если Вам необходимо проверить строку на наличие в ней символов, не обязательно пользоваться функцией strlen. Достаточно проверить первый символ: *s==0 вместо strlen(s)==0. Для того, чтобы перевернуть строку, используйте функцию strrev (STRing REVerse). char *strrev(char *s); wchar_t *_wcsrev(wchar_t *s); char far * far _fstrrev(char far *s) Функция возвращает указатель на перевернутую строку. Для того, чтобы заполнить строку символами (например тире), достаточно вызова strnset. char *strnset(char *s, int ch, size_t n); wchar_t *_wcsnset(wchar_t *s, wchar_t ch, size_t n); char far * far _fstrnset(char far *s, int ch, size_t n); Возвращается указатель на buf, заполненный символом ch длиной в n символов. Для того, чтобы изменить регистр букв в строке применяются функции strlwr и strupr (только латиница). Прототип функции strlwr (STRing LoWeR). char *strlwr(char *s); wchar_t *_wcslwr(wchar_t *s); char far *_fstrlwr(char far *s) Прототип функции strupr (STRing UPpeR). char *strur(char *s); wchar_t *_wcsupr(wchar_t *s); char far *_fstrupr(char far *s) Эти функции возвращают указатель на s. Что не вошло в эту статью? Во-первых, сюда не вошло описание работы со строками, как с массивами char (создание в памяти). Во-вторых не вошли функции strtok (STRing TOKen), strtol и другие функции конвертации строк. В-третьих, здесь описана работа со строками только смомощью стандартных библиотек С. Предлагаю обсудить эту статью. |
Сообщ.
#2
,
|
|
|
Сорри за кривые таблицы, с hr проблемки!
|
Сообщ.
#3
,
|
|
|
с учетом/неучетом регистра в ф-цях strcmp и strcmpi все верно, но только с точностью до "наоборот"
Добавлено в : Цитата myaut, 25.07.04, 08:59 Если сочту нужным, то подправлю |
Сообщ.
#4
,
|
|
|
Adil, подправил!
|
Сообщ.
#5
,
|
|
|
Цитата Это несколько неправильно. Они не создают строк как таковых. Они просто выполняют соответствующие действия над существующими строками.myaut, 25.07.04, 08:59 Для создания строк применяют функции strcpy и strcat Про strncpy надо добавить следующее: если длина копируемой строки превосходит параметр maxlen, то строка-получатель не будет завершена терминирующим символом(нулем). В этом случае такой символ надо ставить вручную. Про strdup надо написать следующее: блок памяти, выделенный для размещения дубликата строки, необходимо вручную удалять при помощи функции free. Цитата Привильно будет *s = '\0'; а проще - *s = 0;myaut, 25.07.04, 08:59 *s="\0"; Цитата myaut, 25.07.04, 08:59 используйте функции с модификатором 'n': Цитата ??? Это ты откуда взял?myaut, 25.07.04, 08:59 Эта функция возвращает количество символов, которые входят и в s2, и в s1. Скажем, при s1="C forever", s2="evr", функция вернет 4, так символ 'е' встретился 2 раза, а символы 'v' и 'r' - по одному разу. P.S. Слово длина пишется с одним Н |
Сообщ.
#6
,
|
|
|
Функции библиотеки dir.h Функции библиотеки io.h, отвечающие за управление файлами на диске Часть 1. Управление файлами и каталогами на диске. Для работы с файлами и каталогами в стандартной библиотеке С предусмотрена билиотека dir.h Из-за того, что на всех платформах API, отвечающее за эти функции различно, горазда удобнее использовать эти функции, решающие проблему переносимости. Сделаю сразу несколько оговорок. Так как С - мультиплатформенный язык, а UNIX/LINUX не поддерживает систему наименования дисков Windows, то за 0 принимают текущий диск, за 1 диск, соответствущий в Windows/DOS путю 'A:', 2 - 'B:' и т. д. Если вы работаете в среде DOS, Вы можете заметить, что некоторые функции переопределены с префиксом _dos. Для их использования необходимо подключить заголовочный файл dos.h Для некоторых функций может потребоваться stdio.h #include <io.h> #include <dir.h> Управление именами файлов Для того, чтобы сформировать путь или поделить его на строки, содержащие устройство (диск), каталог, имя файла и расширение, необходимо использовать соответсвенно функции fnmege (File Name MERGE) и fnsplit (File Name SPLIT) Давайте раcсмотрим их прототипы: void fnmerge(char *path, const char *drive, const char *dir, const char *name, const char *ext); void _wfnmerge(wchar_t *path, const wchar_t *drive, const wchar_t *dir, const wchar_t *name, const wchar_t *ext ); int fnsplit(const char *path, char *drive, char *dir, char *name, char *ext); int _wfnsplit(const wchar_t *path, wchar_t *drive, wchar_t *dir, wchar_t *name, wchar_t *ext ); Длина строк, используемых в этих функциях ограничена. По стандартам ANSI C она равна: Константа 16 бит 32 бита Описание MAXPATH 80 256 Путь MAXDRIVE 3 3 Устройство, включая двоеточие. MAXDIR 66 260 Каталог, включая начальные и конечные обратные слеши (\) MAXFILE 9 256 Имя, без расширения MAXEXT 5 256 Расширение, включает точку Таким образом, чтобы использовать эти функции, необходимо объявить массивы строк длиной в MAX* символов: char path[MAXPATH]; strcpy(path, "C:\\WinNT\\explorer.exe"); /*path содержит C:\WinNT\explorer.exe*/ char drive[MAXDRIVE]; char dir[MAXDIR]; char file[MAXFILE]; char ext[MAXEXT]; fnsplit(path,drive,dir,file,ext); /* Переменная Значение * drive c: * dir \WinNT\ * file explorer * ext .exe */ file[0]=0; /*Очистка имени файла и разширения*/ ext[0]=0; fnmerge(path,drive,dir,file,ext); /*Теперь в path строка C:\WinNT\*/ Для переименования или переименования файла на диске применяют функцию rename. int rename(const char *oldname, const char *newname); int _wrename(const wchar_t *oldname, const wchar_t *newname); Эта функция перемещает/переименовывает файл из пути oldname в newname и возращает -1 или нуль, если операция проведена успешно. Создание и удаление файлов и каталогов Для того, чтобы создать каталог достаточно вызова функции mkdir. Ее преимущество в том, что если в нее передать дополнительный параметр, она доступна в UNIX-системах. Единственный ее параметр - путь к каталогу. int mkdir(const char *path); int _wmkdir(const wchar_t *path); Как и функция rename, при ошибке она возвращает -1, а при успехе - 0. Для того, чтобы удалить созданный раннее каталог достаточно вызова rmdir. К каталогу, который удаляем предъявляются три требования: - он должен буть пустым - он не является текущей рабочей директорией - он не является корневым каталогом int _rmdir(const char *path); int _wrmdir(const wchar_t *path); Для того, чтобы создать файл на диске, используйте функцию _creat, которая создает новый или обрезает существующий файл. Она, как и многие функции io.h работает с файлами с помощью "хэндлов", и поэтому после нее следует вызвать функцию close. Тип файла (текстовый или двоичный) задается глобальной переменной _fmode (O_TEXT или O_BINARY соответственно). Если вы не хотите обрезать старый файл, воспользуйтесь функцией creatnew. int creatnew(const char *path, int mode /*или int attrib*/); При ошибке возвращает -1, при успехе нуль. Первый параметр указывает на путь к файлу, второй на требуемые аттрибуты: Атрибут Объяснение FA_RDONLY Только для чтения FA_HIDDEN Скрытый FA_SYSTEM Системный int _creat(const char *path, int amode); int _wcreat(const wchar_t *path, int amode); Первый параметр - путь к создаваемогу файлу, второй - режим файла. Файл пожет быть открыт и для записи, и для чтения, и для обеих операций. Значение режима Доступ S_IWRITE Разрешение на запись S_IREAD Разрешение на чтение S_IREAD|S_IWRITE Разрешение на запись и чтение Эти константы храняться в библиотеке sys/stat.h Для того, чтобы настроить разрешения для каталога (аналогично режиму файла), используйте функцию chmod. int chmod(const char *path, int amode); int _wchmod(const wchar_t *path, int amode); Функция устанавливает режим amode для каталога path. Для того, чтобы узнать режим файла, используйте функцию access. int access(const char *filename, int amode); int _waccess(const wchar_t *filename, int amode); Определяет возможен ли доступ к файлу filename при режиме amode. Значение Объяснение 6 Возможно ли чтение и запись 4 Возможно ли чтение 2 Возможна ли запись 1 Выполнение (игнорируется) 0 Проверить только на наличие Функция access возвращает значение 0, если файл имеет заданный режим mode. Возвращаемое значение -1 свидетельствует о том, что названный файл не существует или недоступен в заданном amode. Существует два способа удалить файл: через функцию _unlink или remove. int remove(const char *filename); int _wremove(const wchar_t *filename); Функция удаляет файл filename и возвращает нуль при успехе. Ее аналог - функция _unlink еще не утверждена стандартом ANSI C. int _unlink(const char *filename); int _wunlink(const wchar_t *filename); Замечание: если файл открыт, следует закрыть его перед удалением. Поиск файлов по маске Для того, чтобы создать свой файловый броузер программисты используют метод, называемый поиском файлов по маске. Он заключается в том, что в текущей папке находятся все файлы, удовлетворяющие данной маске. При каждом новом вызове функций программа получает данные о следующем файле. Как правило, для реализации этого метода требуется три функции: - Инициализация поиска. Поиск первого файла. - Поиск n-нного файла (в цикле) - Завершение поиска. Для операционной системы MSDOS этими функциями соответственно являются _dos_findfirst, _dos_findnext. Заключительная функция отсутствует, поиск завершает _dos_findnext. Если Вы примените этот метод в Win32, Вам потребуются функции WinAPI FindFirstFile, FindNextFile, FindClose. Для UNIX - систем следует воспользоваться библиотекой dirent.h и функциями opendir, readdir, closedir и rewinddir. Нже будет рассмотрен пример для DOS. Для того, чтобы начать поиск следует указать маску поиска, параметры поиска и место в памяти, куда будут помещаться выходные данные. или struct find_t { char reserved[21]; /* резерв */ char attrib; /* атрибуты файла */ int wr_time; /* время создания */ int wr_date; /* дата создания */ long size; /* размер файла */ char name[13]; /* имя 8.3 */ }; unsigned findfirst(const char *pathname, int attrib, struct find_t *ffblk); /* В некоторых компиляторах - _dos_findfirst */ Маской является приблизительное наименование файла, например: Маска Объяснение *.* Все файлы с расширением * Все файлы *.txt Все файлы txt ????? Файлы с именем из пяти букв *.? Все файлы с расширением из одной буквы a* Все файлы, начинающиеся с буквы 'a' a?? Все файлы с именем из трех букв, первая из которых 'a' В качестве параметра attrib передаются параметры (атрибуты) файла. Они могут объединяться: FA_HIDDEN | FA_RDONLY. Следует обратиться к справке вашего компилятора, чтобы узнать полный список названий атрибутов. Атрибут Альтернативное название Объяснение FA_NORMAL _A_NORMAL Нормальный FA_RDONLY _A_RDONLY Только для чтения FA_HIDDEN _A_HIDDEN Скрытый FA_SYSTEM _A_SYSTEM Системный FA_LABEL _A_VOLID Метка тома FA_DIREC _A_SUBDIR Папка FA_ARCH _A_ARCH Архивный Когда найден первый файл, следует вызвать функцию findnext. или /* В некоторых компиляторах - _dos_findnext */ unsigned findnext(struct find_t *ffblk); Вот пример поиска файлов в текущей папке (MSDOS/BC5). find_t files[128]; /*До 128 файлов*/ struct find_t ffblk; int maxfiles = 0; int done; done = _dos_findfirst("*.*",_A_NORMAL|_A_SUBDIR,&ffblk); /*Поиск файлов и папок*/ while (!done) { maxfiles++; if(maxfiles==120) break; memcpy(&files[maxfiles],&ffblk, sizeof(find_t)); done = _dos_findnext(&ffblk); } Работа с переменными окружения Для того, чтобы узнать текущее состояние Дисковой ОС следует воспользоваться функциями, управляющими окружением. Вот, что входит в окружение. Для того, чтобы управлять текущим диском, используются функции getdisk/setdisk. int getdisk(void); int setdisk(int drive); getdisk возвращает текущий диск (0 - 'A', 1 - 'B', ...) В setdisk передается номер диска, который должен стать текущим, а возвращаемым значением является количество доступных дисков. Для того, чтобы узнать текущий путь (prompt) используют функцию getcwd. Если Вам нужно установить путь, следует использовать системную команду cd. char *getcwd(char *buf, int buflen); wchar_t *_wgetcwd(wchar_t *buf, int buflen); Эта функция помещает строку длиной до buflen с текущим путем в buf и возвращает указатель на buf. Если произошла ошибка, фйнкция возвращает NULL и устанавливает переменную errno. Для того, чтобы получить прочие перпменные окружения, следует указать параметр env в main: int main(int argc, char* argv[], char* env[]) { ... } Одной из важнейших переменных MSDOS является переменная PATH. Прежде, чем искать в текущем каталоге файл, DOS обращается в пути, установленные в PATH. Для того, чтобы узнать, существует ли такой файл С предусматривает функцию searchpath. char *searchpath(const char *file); wchar_t *wsearchpath( const wchar_t *file ); Ищет файл file в каталогах окружения, возращает путь к файлу или NULL, если такового не существует. ЗЫ. Подправлю! Добавлено в : trainer, tnx. |
Сообщ.
#7
,
|
|
|
Часть вторая - упавление файлами с помощью дескрипторов.
В первой части этой статьи мы уже познакомились с "хэндлами" (handles, descriptors, дескрипторы). Цитата Она, как и многие функции io.h работает с файлами с помощью "хэндлов", и поэтому после нее следует вызвать функцию close. Давайте поподробнеее разберемся с ними. Одной из основных функций является функция open. Эта функция открывает файл по имени path с различными флагами. Флаг указывает функции, какие действия необходимо производить при открытии, а также какие действия разрешены с дескриптором (access) и какие - с файлом (mode): , , для установки режима файла int open(const char *path, int access [, unsigned mode]); int _wopen(const wchar_t *path, int access [, unsigned mode]); Функция возвращает дескриптор файла. Его следует хранить в переменной типа int: int hFile=open("file.txt", O_TEXT | O_RDONLY); Флаг Объяснение O_APPEND Указатель на файл перемещен в конец файла перед каждой операцией записи. O_CREAT Новый файл создан и открыт для записи (аналог _creat). O_EXCL Возвращается значение ошибки, если существует файл, определяемый по path-имени. Только с O_CREATE. O_RDONLY Файл открыт только для чтения; если задается этот флаг, может быть выбран либо флаг O_RDWR, либо O_WRONLY. O_RDWR Файл открыт одновременно для чтения и записи; если задается этот флаг, может быть выбран либо флаг O_RDONLY, либо O_WRONLY. O_TRUNC Существующий файл открыт и усечен к длине 0; этот файл должен иметь разрешение на запись. Содержимое файла уничтожается. O_WRONLY Файл открыт только для чтения; если задан этот флаг, должен быть задан также либо флаг O_RDONLY, либо O_RDWR. O_BINARY Файл открыт в двоичном режиме. O_TEXT Файл открыт в текстовом режиме О разрешениях файла (S_*) говорилось в предыдущей части. Для того, чтобы использовать совместный доступ используют функцию _sopen. , , , int _sopen(char *path, int access, int shflag[, int mode]); int _wsopen(wchar_t *path, int access, int shflag[, int mode]); Эта функция отличается от open параметром shflag (SHare FLAG), этот флаг указывает, какой доступ к файлу имеют другие программы. Он может принимать одно из следующих значений: Значение Описание SH_COMPAT Режим совиестимости SH_DENYRW Запрет на запись и на ятение SH_DENYWR Запрет только на запись SH_DENYRD Запрет только на чтение SH_DENYNONE Разрешает чтение/запись SH_DENYNO Аналогично SH_DENYNONE Если разрешения _sopen действуют во всей ОС, то для блокировки от других процессов используют функции lock/unlock или locking. Для работы с ними в DOS предварительно следует загрузить share.exe int lock(int handle, long offset, long length); Функция блокирует дутпер байтов в файле handle начиная с байта offset. При успехе функция возвращает 0. Для разблокирорования области файла, применяют функцию unlock. int unlock(int handle, long offset, long length); Если Вам нужны расширенные параметры блокировки, используйте функцию locking: int locking(int handle, int cmd, long length); Она блокирует первые length байтов файла handle способом cmd. Значение Действия locking LK_LOCK Блокирует область, при невозможности сделать это, повторяет операцию через 10 секунд LK_RLCK Тоже, что и LK_LOCK. LK_NBLCK Блокирует область, при невозможности сделать это, отказывается от блокировки. LK_NBRLCK Тоже, что и LK_NBLCK. LK_UNLCK Разблокирует ранее заблокированную область. После того, как мы открыли файл, провели с ним каки-нибудь действия, его следуе закрыть функцией close. Единственный параметр этой функции - дескриптор, полученный с помощью функции open: close(hFile). int close(int handle); Как и многие функции, при успехе она возвращает 0, при ошибке - -1. Для того, чтобы сделать копию файла с новым именем, применяют функцию dup2. int dup2(int oldhandle, int newhandle); Она создает дополнительный дескиптор newhandle файла, указываемого oldhandle и возвращает его. Важными функциями также являются read и write. Первая считывает данные из файла, вторая их записывает, однако они не относятся к функциям управления файлами на диске напрямую, и о них я расскажу позже. Автор myaut. Соавторство CBP. |
Сообщ.
#8
,
|
|
|
Часть третья - получение информации о файле.
Так как ФС помимо имени файла хранит еще много различных параметров, я приведу несколько методов получения их. Первый - использование поиска файлов по маске. Для не обязательно иметь конкретное имя файла. Поиск файлов по маске Для того, чтобы создать свой файловый броузер программисты используют метод, называемый поиском файлов по маске. Он заключается в том, что в текущей папке находятся все файлы, удовлетворяющие данной маске. При каждом новом вызове функций программа получает данные о следующем файле. Как правило, для реализации этого метода требуется три функции: - Инициализация поиска. Поиск первого файла. - Поиск n-нного файла (в цикле) - Завершение поиска. Для операционной системы MSDOS этими функциями соответственно являются _dos_findfirst, _dos_findnext. Заключительная функция отсутствует, поиск завершает _dos_findnext. Если Вы примените этот метод в Win32, Вам потребуются функции WinAPI FindFirstFile, FindNextFile, FindClose. Для UNIX - систем следует воспользоваться библиотекой dirent.h и функциями opendir, readdir, closedir и rewinddir. Нже будет рассмотрен пример для DOS. Для того, чтобы начать поиск следует указать маску поиска, параметры поиска и место в памяти, куда будут помещаться выходные данные. или struct find_t { char reserved[21]; /* резерв */ char attrib; /* атрибуты файла */ int wr_time; /* время создания */ int wr_date; /* дата создания */ long size; /* размер файла */ char name[13]; /* имя 8.3 */ }; unsigned findfirst(const char *pathname, int attrib, struct find_t *ffblk); /* В некоторых компиляторах - _dos_findfirst */ Маской является приблизительное наименование файла, например: Маска Объяснение *.* Все файлы с расширением * Все файлы *.txt Все файлы txt ????? Файлы с именем из пяти букв *.? Все файлы с расширением из одной буквы a* Все файлы, начинающиеся с буквы 'a' a?? Все файлы с именем из трех букв, первая из которых 'a' В качестве параметра attrib передаются параметры (атрибуты) файла. Они могут объединяться: FA_HIDDEN | FA_RDONLY. Следует обратиться к справке вашего компилятора, чтобы узнать полный список названий атрибутов. Атрибут Альтернативное название Объяснение FA_NORMAL _A_NORMAL Нормальный FA_RDONLY _A_RDONLY Только для чтения FA_HIDDEN _A_HIDDEN Скрытый FA_SYSTEM _A_SYSTEM Системный FA_LABEL _A_VOLID Метка тома FA_DIREC _A_SUBDIR Папка FA_ARCH _A_ARCH Архивный Когда найден первый файл, следует вызвать функцию findnext. или /* В некоторых компиляторах - _dos_findnext */ unsigned findnext(struct find_t *ffblk); Вот пример поиска файлов в текущей папке (MSDOS/BC5). find_t files[128]; /*До 128 файлов*/ struct find_t ffblk; int maxfiles = 0; int done; done = _dos_findfirst("*.*",_A_NORMAL|_A_SUBDIR,&ffblk); /*Поиск файлов и папок*/ while (!done) { maxfiles++; if(maxfiles==120) break; memcpy(&files[maxfiles],&ffblk, sizeof(find_t)); done = _dos_findnext(&ffblk); } Функции stat, fstat Второй метод - файловая статистика. В С она реализована с помощью функций fstat (stat) int fstat(int handle, struct stat *statbuf); int stat(const char *path, struct stat *statbuf); int _wstat(const wchar_t *path, struct stat *statbuf); Главое отличие fstat от stat заключается в том, что для нее имя файла не обязательно, а достаточно дескриптора (про дескрипторы мы говорили во вотрой части статьи). Второй параметр - указатель на структуру, хранящую файловую статистику. Эта структура принимает такой вид: struct stat { short st_dev; //Дескриптор устройства или номер файла на диске short st_ino; short st_mode; //Режим дескриптора short st_nlink; int st_uid; int st_gid; short st_rdev; long st_size; //Размер в байтах long st_atime; //Файловое время: для NTFS/HPFS - время последнего доступа к файлу long st_mtime; //Файловое время: для NTFS/HPFS - время последней модификации файла long st_ctime; //Файловое время: для NTFS/HPFS - время создания файла }; Для того, чтобы проверить режим дескриптора также объявлены макросы: S_ISDIR(m) - проверяет на директорию S_ISCHR(m) - проверяет на устройство S_ISBLK(m) - проверяет на специальный тип блока S_ISREG(m) - проверяет на файл S_ISFIFO(m) - проверяет на специальный режим FIFO Проверка каждого аттрибута по-отдельности Для некоторых аттрибутов проверку можно провести специальными функциями, например filelength возвращает длину файла handle, getftime позволяет получить дату и время создания файла. P. S. 2trainer, если напишешь про POSIX-функции opendir etc., буду благодарен и запишу в соавторство. P. P. S. Пункт "Поиск файлов по маске" перенесен из части первой. |
Сообщ.
#9
,
|
|
|
Краткое знакомство с фукциями math.h Наверное, все знакомы с программой Калькулятор из Microsoft® Windows® и ее режимом "Инженерный". В состав стандартной библиотеки С входит огромное количество математических функций, аналогичных действиям из инженерного калькулятора. Я построил эту статью несколько иначе, чем все предыдущие статьи. abs - абсолютное значение (модуль) acos, acosl - арккосинус asin, asinl - арксинус atan, atanl - арктангенс atan2, atan2l - арктангенс2 cabs, cabsl - абсолбтное значение комплексного числв ceil, ceill - округление вверх, наименьшее целое, не меньшее х cos, cosl - косинус cosh, coshl - косинус гиперболический exp, expl - экспонента fabs, fabs - абсолютный модуль дроби floor, floorl - округление вниз, наибольшее целое, не большее х fmod, fmodl - остаток от деления, аналог операции % frexp, frexpl - разделяет число на мантиссу и экспоненту hypot, hypotl - гипотенуза labs - модуль длинного целого ldexp, ldexpl - произведение числа на два в степени exp log, logl - логарифм натуральный log10, log101 - логарифм лесятичный modf, modfl - разделяет на целую и на дробную часть poly, polyl - полином pow, powl - степень pow10, pow10l - степень десяти sin, sinl - синус sinh, sinhl - синус гиперболический sqrt, sqrtl - квадратный корень tan, tanl - тангенс tanh, tanhl - тангенс гиперболический Для работы с псевдослучайными числами применяются функции stdlib.h randomize (инициализирует генератор) и rand (генерирует число). Для некоторых компьютеров randomize будет неэффективен и гораздо лучше будет использовать функцию srand, использующую системное время. Для псевдослучайных чисел, не ограниченных RAND_MAX можно написать собственный макрос: #define rand2(a, b) (rand()%b)+a Генерирует псевдослучайное число между a и b. |
Сообщ.
#10
,
|
|
|
Цитата Для того, чтобы сделать копию файла с новым именем, применяют функцию dup2. int dup2(int oldhandle, int newhandle); Она копирует данные из oldhandle в newhandle. Возвращает newhandle. В корне неверно %) Цитата Для работы с псевдослучайными числами применяются функции stdlib.h randomize (инициализирует генератор) и rand (генерирует число). Если хотите чтоб ваш код компилился не только борландом, но и другими компилерами, то вместо randomize юзайте че-нить более стандартное.. типа srand(системное время); |
Сообщ.
#11
,
|
|
|
Допиши, чтобы было верно, я тебя в соавторство запишу!
|
Сообщ.
#12
,
|
|
|
Возможно и не в тему - но спасибо автору
Затеяно архиполезное дело. |
Сообщ.
#13
,
|
|
|
еще не вчитывался только пролистал но мне нравится!! АВТОРУ РЕСПЕКТ!
P.S. У меня была такая тема курсовой где ты был месяца 2 назад ) я там такой бред написал лиш бы отмазатся (почему пояснять небуду особеенности моего инситута) |
Сообщ.
#14
,
|
|
|
Я кстати готовлю аналогичный вариант на с php скриптами, поиском и скриптами. Когда зарегю сайт, кину линку! Завтра в планах еще чего-нибудь написать!
|
Сообщ.
#15
,
|
|
|
хм... а по подробнее что ты собрался на пхп делать можт я проведу аналогию с перлой! будет полезно всем!
|