На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (4) [1] 2 3 ... Последняя » все  ( Перейти к последнему сообщению )  
> Стандартная библиотека С , серия статей
    Так как справочной литературы по стандартной библиотеке С не так уж и много, я создал небольшое подобие
    помощи по главной библиотеке великого и могучего. Когда я отправил этот пост, будет готова статья по string.h
    и статья по использованию файловых функций. Также вы сможете ознакомиться с возможностями по оптимизации
    и с узкими местами приведенных функций. Обсуждаем первую статью! Об очепятках и неточностях можно писать прямо
    в этом топике! Если сочту нужным, то подправлю. Когда вся серия статей будет готова, отправлю в FAQ.

    Стандартная библиотека С.


    Функции библиотеки string.h


    Для обработки строк в программах, написанных на С, применяют билиотеку string.h. В нее входит достаточно
    большое количество функций. Перед этой библиотеки использованием следует ее подключить:
    ExpandedWrap disabled
      #include <string.h>


    Создание строк
    Для создания (не в памяти, аих инициализации) строк применяют функции strcpy и strcat, а также несколько
    их аналогов. Перед использованием функции strcpy (STRing CoPY) следует проверить, выделена ли память
    под обе строки. Объявление функции копирования строк:
    user posted image
    ExpandedWrap disabled
      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).
    Объявление функции добавления строк:
    user posted image
    ExpandedWrap disabled
      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. За счет того, что функции возвращают указатель на полученную
    строку, имеется возможность использовать вложенные вызовы. Премер использования функций создания строк.
    ExpandedWrap disabled
      #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 она объявлена так:
    user posted image
    user posted image
    ExpandedWrap disabled
      char *strdup(const char *s);
      wchar_t *_wcsdup(const wchar_t *s);
      char far *_fstrdup(const char far *s)


    С использованием этих функций связано много подводных камней. Например, иногда под одну из строк не выделена
    память, это распространенная ошибка.
    • Обобщенный вариант strcpy - memcpy.
    • Не следует злоупотреблять использованием функции strncpy, так как все символы, которые не достают до
      длины maxlen заполняет нулями, это может вызвать "притормаживание" программы.
    • Для того, чтобы проинициализировать строку, некоторые программисты копируют в нее пустую строку: strcpy(s, " ");
      Гораздо быстрее будет код: *s=0;
    • Вместо того, чтобы использовать strcat, можно вызвать функцию strcpy, а указатель переместить на конец строки.
    • Функции копирования (кроме strncpy) не проверяют длину строки. Размер приемника должен быть больше, чем
      размер источника на 1 символ (для нуль-терминатора).
    • Функция strdup не предусмотрена стандартами ANSI C.
    • При вызове функции strncpy следует помнить, что если длина копируемой строки превосходит параметр maxlen,
      то строка-получатель не будет завершена терминирующим символом(нулем). В этом случае такой символ надо ставить вручную.

    Сравнее строк и поиск подстрок.
    Сравнее строк представлено в С функциями strcmp, strncmp, strncmpi (strnicmp) , strcmpi (stricmp). Следует
    заметить, что функции strcmpi и stricmp, а также strncmpi и strnicmp идентичны.
    Самый простой способ сравнить две строки, использовать функцию strcmp (STRing CoMPare). Эта функция
    сравнивает две строки без учета регистра. Протитипы функций выглядят так:
    user posted image
    ExpandedWrap disabled
      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. Следует
    сделать важную оговорку: регистр определяется только для латиницы. Объявлена эта функция так:
    ExpandedWrap disabled
      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':
    ExpandedWrap disabled
      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).
    Объявлена она так:
    user posted image
    ExpandedWrap disabled
      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). Ее прототип:
    user posted image
    ExpandedWrap disabled
      /* Для С */
      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, для С и С++
    прототип разный.
    user posted image
    ExpandedWrap disabled
      /* 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 объявлена так:
    user posted image
    ExpandedWrap disabled
      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.
    user posted image
    ExpandedWrap disabled
      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);


    Общие замечания.
    • Есть способ избежать вызова strcmp, если сначала сравнить первые символы. В таком случае, если они не равны,
      то одна строка не соответствует другой.
    • Как я уже сказал, регистр в strcmpi и т. п. функциях определяется только для латиницы.
    • По традициям С, в функциях обработки символов используется тип int, хотя если число будет больше 128 (255),
      функция будет работать с ошибкой.

    Прочие функции
    Для того, чтобы вычислить длину строки, следует использовать функцию strlen (STRing LENgth) вместо оператора
    sizeof.
    ExpandedWrap disabled
      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).
    user posted image
    user posted image
    user posted image
    ExpandedWrap disabled
      char *strrev(char *s);
      wchar_t *_wcsrev(wchar_t *s);
      char far * far _fstrrev(char far *s)

    Функция возвращает указатель на перевернутую строку.

    Для того, чтобы заполнить строку символами (например тире), достаточно вызова strnset.
    user posted image
    ExpandedWrap disabled
      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).
    user posted image
    ExpandedWrap disabled
      char *strlwr(char *s);
      wchar_t *_wcslwr(wchar_t *s);
      char far *_fstrlwr(char far *s)


    Прототип функции strupr (STRing UPpeR).
    user posted image
    user posted image
    user posted image
    ExpandedWrap disabled
      char *strur(char *s);
      wchar_t *_wcsupr(wchar_t *s);
      char far *_fstrupr(char far *s)

    Эти функции возвращают указатель на s.

    Что не вошло в эту статью?
    Во-первых, сюда не вошло описание работы со строками, как с массивами char (создание в памяти).
    Во-вторых не вошли функции strtok (STRing TOKen), strtol и другие функции конвертации строк.
    В-третьих, здесь описана работа со строками только смомощью стандартных библиотек С.

    Предлагаю обсудить эту статью.
    Сообщение отредактировано: myaut -
      Сорри за кривые таблицы, с hr проблемки!
        с учетом/неучетом регистра в ф-цях strcmp и strcmpi все верно, но только с точностью до "наоборот" :)

        Добавлено в :
        Цитата
        myaut, 25.07.04, 08:59
        Если сочту нужным, то подправлю
        :D
          Adil, подправил!
            Цитата
            myaut, 25.07.04, 08:59
            Для создания строк применяют функции strcpy и strcat
            Это несколько неправильно. Они не создают строк как таковых. Они просто выполняют соответствующие действия над существующими строками.
            Про strncpy надо добавить следующее: если длина копируемой строки превосходит параметр maxlen, то строка-получатель не будет завершена терминирующим символом(нулем). В этом случае такой символ надо ставить вручную.
            Про strdup надо написать следующее: блок памяти, выделенный для размещения дубликата строки, необходимо вручную удалять при помощи функции free.
            Цитата
            myaut, 25.07.04, 08:59
            *s="\0";
            Привильно будет *s = '\0'; а проще - *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. Слово длина пишется с одним Н :)
              Функции библиотеки dir.h

              Функции библиотеки io.h, отвечающие за управление файлами на диске


              Часть 1. Управление файлами и каталогами на диске.

              Для работы с файлами и каталогами в стандартной библиотеке С предусмотрена билиотека dir.h Из-за того, что
              на всех платформах API, отвечающее за эти функции различно, горазда удобнее использовать эти функции,
              решающие проблему переносимости. Сделаю сразу несколько оговорок. Так как С - мультиплатформенный язык,
              а UNIX/LINUX не поддерживает систему наименования дисков Windows, то за 0 принимают текущий диск, за 1
              диск, соответствущий в Windows/DOS путю 'A:', 2 - 'B:' и т. д. Если вы работаете в среде DOS, Вы можете
              заметить, что некоторые функции переопределены с префиксом _dos. Для их использования необходимо подключить
              заголовочный файл dos.h Для некоторых функций может потребоваться stdio.h
              ExpandedWrap disabled
                #include <io.h>
                #include <dir.h>


              Управление именами файлов

              Для того, чтобы сформировать путь или поделить его на строки, содержащие устройство (диск), каталог, имя файла
              и расширение, необходимо использовать соответсвенно функции fnmege (File Name MERGE) и fnsplit (File Name SPLIT)
              Давайте раcсмотрим их прототипы:
              user posted image
              user posted image
              user posted image
              ExpandedWrap disabled
                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* символов:
              ExpandedWrap disabled
                   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.
              user posted image
              user posted image
              ExpandedWrap disabled
                int rename(const char *oldname, const char *newname);
                int _wrename(const wchar_t *oldname, const wchar_t *newname);

              Эта функция перемещает/переименовывает файл из пути oldname в newname и возращает -1 или нуль,
              если операция проведена успешно.
              • Я настоятельно рекомендую Вам пользоваться ограничениями MAX* во избежание недоразумений
              • По причине того, что в С обратный слеш (\) используется для внутренних целей, при объявлении пути
                слеш удваивают.

              Создание и удаление файлов и каталогов

              Для того, чтобы создать каталог достаточно вызова функции mkdir. Ее преимущество в том, что если в нее
              передать дополнительный параметр, она доступна в UNIX-системах. Единственный ее параметр - путь к каталогу.
              user posted image
              user posted image
              ExpandedWrap disabled
                int mkdir(const char *path);
                int _wmkdir(const wchar_t *path);

              Как и функция rename, при ошибке она возвращает -1, а при успехе - 0.

              Для того, чтобы удалить созданный раннее каталог достаточно вызова rmdir. К каталогу, который удаляем предъявляются
              три требования:
              - он должен буть пустым
              - он не является текущей рабочей директорией
              - он не является корневым каталогом
              user posted image
              user posted image
              ExpandedWrap disabled
                int _rmdir(const char *path);
                int _wrmdir(const wchar_t *path);


              Для того, чтобы создать файл на диске, используйте функцию _creat, которая создает новый или обрезает существующий
              файл. Она, как и многие функции io.h работает с файлами с помощью "хэндлов", и поэтому после нее следует вызвать
              функцию close. Тип файла (текстовый или двоичный) задается глобальной переменной _fmode (O_TEXT или O_BINARY
              соответственно). Если вы не хотите обрезать старый файл, воспользуйтесь функцией creatnew.
              user posted image
              user posted image
              user posted image
              ExpandedWrap disabled
                int creatnew(const char *path, int mode /*или int attrib*/);

              При ошибке возвращает -1, при успехе нуль. Первый параметр указывает на путь к файлу, второй на требуемые аттрибуты:



              Атрибут Объяснение


              FA_RDONLY Только для чтения
              FA_HIDDEN Скрытый
              FA_SYSTEM Системный




              user posted image
              user posted image
              ExpandedWrap disabled
                int _creat(const char *path, int amode);
                int _wcreat(const wchar_t *path, int amode);

              Первый параметр - путь к создаваемогу файлу, второй - режим файла. Файл пожет быть открыт и для записи, и для
              чтения, и для обеих операций.
              user posted image



              Значение режима Доступ


              S_IWRITE Разрешение на запись
              S_IREAD Разрешение на чтение
              S_IREAD|S_IWRITE Разрешение на запись и чтение


              Эти константы храняться в библиотеке sys/stat.h

              Для того, чтобы настроить разрешения для каталога (аналогично режиму файла), используйте функцию chmod.
              user posted image
              user posted image
              ExpandedWrap disabled
                int chmod(const char *path, int amode);
                int _wchmod(const wchar_t *path, int amode);

              Функция устанавливает режим amode для каталога path.

              Для того, чтобы узнать режим файла, используйте функцию access.
              user posted image
              user posted image
              ExpandedWrap disabled
                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.
              user posted image
              ExpandedWrap disabled
                int remove(const char *filename);
                int _wremove(const wchar_t *filename);

              Функция удаляет файл filename и возвращает нуль при успехе. Ее аналог - функция _unlink еще не утверждена стандартом
              ANSI C.
              user posted image
              user posted image
              ExpandedWrap disabled
                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.

              Для того, чтобы начать поиск следует указать маску поиска, параметры поиска и место в памяти, куда будут помещаться
              выходные данные.
              user posted image или user posted image
              user posted image
              user posted image
              user posted image
              ExpandedWrap disabled
                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.
              user posted image или user posted image
              user posted image
              user posted image
              user posted image
              ExpandedWrap disabled
                /* В некоторых компиляторах - _dos_findnext */
                unsigned findnext(struct find_t *ffblk);


              Вот пример поиска файлов в текущей папке (MSDOS/BC5).
              ExpandedWrap disabled
                  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);
                  }


              Работа с переменными окружения

              Для того, чтобы узнать текущее состояние Дисковой ОС следует воспользоваться функциями, управляющими окружением.
              Вот, что входит в окружение.
              1. Текущий диск
              2. Текущий каталог
              3. Текущий путь

              Для того, чтобы управлять текущим диском, используются функции getdisk/setdisk.
              user posted image
              user posted image
              user posted image
              ExpandedWrap disabled
                int getdisk(void);
                int setdisk(int drive);

              getdisk возвращает текущий диск (0 - 'A', 1 - 'B', ...)
              В setdisk передается номер диска, который должен стать текущим, а возвращаемым значением является количество
              доступных дисков.
              Для того, чтобы узнать текущий путь (prompt) используют функцию getcwd. Если Вам нужно установить путь, следует
              использовать системную команду cd.
              user posted image
              user posted image
              user posted image
              ExpandedWrap disabled
                char *getcwd(char *buf, int buflen);
                wchar_t *_wgetcwd(wchar_t *buf, int buflen);

              Эта функция помещает строку длиной до buflen с текущим путем в buf и возвращает указатель на buf. Если произошла ошибка,
              фйнкция возвращает NULL и устанавливает переменную errno.

              Для того, чтобы получить прочие перпменные окружения, следует указать параметр env в main:
              ExpandedWrap disabled
                int main(int argc, char* argv[], char* env[]) {
                 ...
                }

              Одной из важнейших переменных MSDOS является переменная PATH. Прежде, чем искать в текущем каталоге
              файл, DOS обращается в пути, установленные в PATH. Для того, чтобы узнать, существует ли такой файл С предусматривает
              функцию searchpath.
              user posted image
              user posted image
              user posted image
              ExpandedWrap disabled
                char *searchpath(const char *file);
                wchar_t *wsearchpath( const wchar_t *file );

              Ищет файл file в каталогах окружения, возращает путь к файлу или NULL, если такового не существует.

              ЗЫ. Подправлю!

              Добавлено в :
              trainer, tnx.
                Часть вторая - упавление файлами с помощью дескрипторов.

                В первой части этой статьи мы уже познакомились с "хэндлами" (handles, descriptors, дескрипторы).
                Цитата
                Она, как и многие функции io.h работает с файлами с помощью "хэндлов", и поэтому после нее следует
                вызвать функцию close.

                Давайте поподробнеее разберемся с ними.

                Одной из основных функций является функция open. Эта функция открывает файл по имени path с различными флагами.
                Флаг указывает функции, какие действия необходимо производить при открытии, а также какие действия разрешены
                с дескриптором (access) и какие - с файлом (mode):
                user posted image,
                user posted image,
                user posted image для установки режима файла
                user posted image
                ExpandedWrap disabled
                  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.
                user posted image,
                user posted image,
                user posted image,
                user posted image
                user posted image
                ExpandedWrap disabled
                  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
                user posted image
                user posted image
                user posted image
                ExpandedWrap disabled
                  int lock(int handle, long offset, long length);

                Функция блокирует дутпер байтов в файле handle начиная с байта offset. При успехе функция возвращает 0.
                Для разблокирорования области файла, применяют функцию unlock.
                ExpandedWrap disabled
                  int unlock(int handle, long offset, long length);

                Если Вам нужны расширенные параметры блокировки, используйте функцию locking:
                user posted image
                user posted image
                user posted image
                ExpandedWrap disabled
                  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).
                user posted image
                user posted image
                ExpandedWrap disabled
                  int close(int handle);

                Как и многие функции, при успехе она возвращает 0, при ошибке - -1.

                Для того, чтобы сделать копию файла с новым именем, применяют функцию dup2.
                user posted image
                user posted image
                ExpandedWrap disabled
                  int dup2(int oldhandle, int newhandle);

                Она создает дополнительный дескиптор newhandle файла, указываемого oldhandle и возвращает его.

                Важными функциями также являются read и write. Первая считывает данные из файла, вторая их записывает,
                однако они не относятся к функциям управления файлами на диске напрямую, и о них я расскажу позже.

                Автор myaut.
                Соавторство CBP.
                Сообщение отредактировано: myaut -
                  Часть третья - получение информации о файле.

                  Так как ФС помимо имени файла хранит еще много различных параметров, я приведу несколько методов получения их.
                  Первый - использование поиска файлов по маске. Для не обязательно иметь конкретное имя файла.

                  Поиск файлов по маске
                  Для того, чтобы создать свой файловый броузер программисты используют метод, называемый поиском файлов по

                  маске.
                  Он заключается в том, что в текущей папке находятся все файлы, удовлетворяющие данной маске. При каждом
                  новом вызове функций программа получает данные о следующем файле. Как правило, для реализации этого метода
                  требуется три функции:
                  - Инициализация поиска. Поиск первого файла.
                  - Поиск n-нного файла (в цикле)
                  - Завершение поиска.

                  Для операционной системы MSDOS этими функциями соответственно являются _dos_findfirst, _dos_findnext.
                  Заключительная функция отсутствует, поиск завершает _dos_findnext. Если Вы примените этот метод в Win32, Вам
                  потребуются функции WinAPI FindFirstFile, FindNextFile, FindClose. Для UNIX - систем следует воспользоваться
                  библиотекой dirent.h и функциями opendir, readdir, closedir и rewinddir. Нже будет рассмотрен пример для DOS.

                  Для того, чтобы начать поиск следует указать маску поиска, параметры поиска и место в памяти, куда будут

                  помещаться
                  выходные данные.
                  user posted image или user posted image
                  user posted image
                  user posted image
                  user posted image
                  ExpandedWrap disabled
                    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.
                  user posted image или user posted image
                  user posted image
                  user posted image
                  user posted image
                  ExpandedWrap disabled
                    /* В некоторых компиляторах - _dos_findnext */
                    unsigned findnext(struct find_t *ffblk);


                  Вот пример поиска файлов в текущей папке (MSDOS/BC5).
                  ExpandedWrap disabled
                      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)
                  user posted image
                  user posted image
                  ExpandedWrap disabled
                    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 заключается в том, что для нее имя файла не обязательно, а достаточно дескриптора
                  (про дескрипторы мы говорили во вотрой части статьи). Второй параметр - указатель на структуру, хранящую
                  файловую статистику. Эта структура принимает такой вид:
                  ExpandedWrap disabled
                    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. Пункт "Поиск файлов по маске" перенесен из части первой.
                    Краткое знакомство с фукциями 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 можно написать собственный макрос:
                    ExpandedWrap disabled
                      #define rand2(a, b) (rand()%b)+a

                    Генерирует псевдослучайное число между a и b.
                    Сообщение отредактировано: myaut -
                      Цитата
                      Для того, чтобы сделать копию файла с новым именем, применяют функцию dup2.
                      int dup2(int oldhandle, int newhandle);
                      Она копирует данные из oldhandle в newhandle. Возвращает newhandle.

                      В корне неверно %)

                      Цитата
                      Для работы с псевдослучайными числами применяются функции stdlib.h randomize (инициализирует генератор) и rand (генерирует число).

                      Если хотите чтоб ваш код компилился не только борландом, но и другими компилерами, то вместо randomize юзайте че-нить более стандартное.. типа srand(системное время);
                        Допиши, чтобы было верно, я тебя в соавторство запишу! :wall:
                          Возможно и не в тему - но спасибо автору :D
                          Затеяно архиполезное дело.
                            еще не вчитывался только пролистал но мне нравится!! АВТОРУ РЕСПЕКТ!

                            P.S.
                            У меня была такая тема курсовой где ты был месяца 2 назад ;))
                            я там такой бред написал лиш бы отмазатся (почему пояснять небуду особеенности моего инситута)
                              Я кстати готовлю аналогичный вариант на с php скриптами, поиском и скриптами. Когда зарегю сайт, кину линку! Завтра в планах еще чего-нибудь написать!
                                хм... а по подробнее что ты собрался на пхп делать можт я проведу аналогию с перлой! будет полезно всем!
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1008 ]   [ 16 queries used ]   [ Generated: 21.05.24, 18:32 GMT ]