Рефераты. Теория вычислительных процессов и структур

         main()

         {

             int filedes;

             /* Открыть файл, используя постоянную O_RDWR из <fcnt1.h> */

             /* Файл открывается для чтения / записи */

             if ((filedes=open(workfile, O_RDWR)) = = -1)

             {

                 printf (“Невозможно открыть %s\n”, workfile);

                 exit (1);        /* Выход по ошибке */

             }

             /* Остальная программа */

             exit (0);          /* Нормальный выход */

         }

Вызов open может использоваться для создания файла, например:

filedes = open (“/tmp/newfile”, O_WRONLY | O_CREAT, 0644);

Здесь объединены флаги O_CREAT и O_WRONLY, задающие создание файла /tmp/newfile при помощи вызова open. Если /tmp/newfile не существует, то будет создан файл нулевой длины с таким именем и открыт только для записи.

Параметр mode содержит число, определяющее права доступа к файлу, указывающие, кто из пользователей системы может осуществлять чтение, запись или выполнение файла. Пользователь, создавший файл, может выполнять чтение из файла и запись в него. Остальные пользователи будут иметь доступ только для чтения файла.

Следующая программа создаёт файл newfile в текущем каталоге:

         # include <stdlib.h>  

         # include <fcnt1.h>

         #define PERMS 0644     /*  Права доступа при открытии с O_CREAT */

         char *filename=”newfile”;   

         main()

         {

             int filedes;

             if ((filedes=open (filename, O_RDWR | O_CREAT,  PERMS)) = = -1)

             {

                 printf (“Невозможно открыть %s\n”, filename);

                 exit (1);        /* Выход по ошибке */

             }

             /* Остальная программа */

             exit (0);         

         }

Другой способ создания файла заключается в использовании системного вызова creat. Так же, как и вызов open, он возвращает либо ненулевой дескриптор файла, либо –1 в случае ошибки. Если файл успешно создан, то возвращаемое значение является дескриптором этого файла, открытого для записи. Вызов creat осуществляется так:

# include <sys / types.h>

# include <sys / stat.h>

# include <fcnt1.h>

int creat (const char *pathname, mode_t mode);

Первый параметр pathname указывает на маршрутное имя файла UNIX, определяющее имя создаваемого файла и путь к нему. Так же, как и в случае вызова open, параметр mode задаёт права доступа. При этом, если файл существует, то второй параметр также игнорируется. Тем не менее, в отличие от вызова open, в результате вызова creat файл всегда будет усечён до нулевой длины. Пример использования вызова creat:

filedes = creat (“/tmp/newfile”, 0644);

что эквивалентно вызову:

filedes = open (“/tmp/newfile”, O_WRONLY | O_CREAT | O_TRUNC, 0644);

Следует отметить, что вызов creat всегда открывает файл только для записи. Например, программа не может создать файл при помощи creat, записать в него данные, затем вернуться назад и попытаться прочитать данные из файла, если предварительно не закроет его и не откроет снова при помощи вызова open.

Библиотечная процедура fopen является эквивалентом вызова open:

#include <stdio.h>

FILE *fopen (const char *filename, const char *type);

Процедура fopen открывает файл, заданный параметром filename, и связывает с ним структуру FILE. В случае успешного завершения процедура fopen возвращает указатель на структуру FILE, идентифицирующую открытый файл; объект FILE * также часто называют открытым потоком ввода / вывода (эта структура FILE является элементом внутренней таблицы). В случае неудачи процедура fopen возвращает нулевой указатель NULL. При этом, так же, как и для open, переменная errno будет содержать код ошибки, указывающий на её причину.

Второй параметр процедуры fopen указывает на строку, определяющую режим доступа. Она может принимать следующие основные значения:

r - открыть файл filename только для чтения (если файл не существует, то процедура fopen вернёт нулевой указатель NULL);

w - создать файл filename и открыть его только для записи (если файл не существует, то он будет усечён до нулевой длины);

а - открыть файл filename только для записи, все данные будут добавляться в конец файла (если файл не существует, он создаётся).

Следующий пример программы показывает использование процедуры fopen. При этом, если файл indata существует, то он открывается для чтения, а файл outdata создаётся (или усекается до нулевой длины, если он существует). Процедура fatal предназначена для вывода сообщения об ошибке. Она просто передаёт свой аргумент процедуре perror, а затем вызывается exit для завершения работы программы:

         #include <stdio.h>

         char *inname = “indata”;

         char *outname = “outdata”;

         main()

         {

             FILE *inf, *outf;

             if ((inf = fopen (inname, “r”)) = = NULL)

                 fatal (“Невозможно открыть входной файл”);

             if ((outf = fopen (outname, “w”)) = = NULL)

                 fatal (“Невозможно открыть выходной файл”);


             /* Выполняются какие-либо действия */

             exit (0);      

}

Основные процедуры для ввода строк называются gets и fgets:

# include <stdio.h>

char *gets (char *buf);

char  *fgets (char *buf, int nsize, FILE *inf);

Процедура gets считывает последовательность символов из потока стандартного ввода (stdin), помещая все символы в буфер, на который указывает аргумент buf. Символы считываются до тех пор, пока не встретится символ перевода строки или конца файла. Символ перевода строки newline отбрасывается, и вместо него в буфер помещается нулевой символ, образуя завершённую строку. В случае возникновения ошибки или при достижении конца файла возвращается значение NULL.

Процедура fgets является обобщённой версией процедуры gets. Она считывает из потока inf в буфер buf до тех пор, пока не будет считано nsize-1 символов или не встретится раньше символ перевода строки newline, или не будет достигнут конец файла. В процедуре fgets символы перевода строки newline не отбрасываются, а помещаются в конец буфера (это позволяет вызывающей функции определить, в результате чего произошёл возврат из процедуры fgets). Как и процедура gets, процедура fgets возвращает указатель на буфер buf в случае успеха и NULL – в противном случае.

Следующая процедура yesno использует процедуру fgets для получения положительного или отрицательного ответа от пользователя, она также вызывает макрос isspace для пропуска пробельных символов в строке ответа:

         # include <stdio.h>

         # include <stype.h>

         #define YES   1

         #define NO   0

         #define ANSWSZ   80

         static char *pdefault = “Наберите ‘y’ (YES), или ‘n’ (NO)”;

         static char *error = “Неопределённый ответ”;

         int yesno (char *prompt)

         {

             char buf [ANSWSZ], *p_use, *p;

             /* Выводит приглашение, если оно не равно NULL

·        Иначе использует приглашение по умолчанию pdefault */

             p_use = (prompt != NULL) ? prompt : pdefault;

    /* Бесконечный цикл до получения правильного ответа */

             for (;;)

             {

                 /* Выводит приглашение */

                 printf (“%s >”, p_use );

                 if (fgets (buf, ANSWSZ, stdin) = = NULL)

                     return EOF;

             /* Удаляет пробельные символы */

             for (p = buf; isspace (*p); p++)

                 ;

             switch (*p)

    {

        case ‘Y’:

        case ‘y’:

            return (YES);

        case ‘N’:

        case ‘n’:

            return (NO);

        default:

            printf (“\n%s\n”, error);

      } 

    }

}

Обратными процедурами для gets и fgets будут соответственно процедуры  puts и fputs:

# include <stdio.h>

int puts (const char *string);

int fputs (const char *string, FILE *outf);

Процедура puts записывает все символы (кроме завершающего нулевого символа) из строки string на стандартный вывод (stdout). Процедура fputs записывает строку string в поток outf. Для обеспечения совместимости со старыми версиями системы процедура puts добавляет в конце символ перевода строки, процедура же fputs не делает этого. Обе функции возвращают в случае ошибки значение EOF.

Для осуществления форматированного вывода используются процедуры printf и fprintf:

# include <stdio.h>

int printf (const char *fmt, arg1, arg2 … argn);

int fprintf (FILE *outf, const char *fmt, arg1, arg2 … argn);

Каждая из этих процедур получает строку формата вывода fmt и переменное число аргументов произвольного типа, используемых для формирования выходной строки вывода. В выходную строку выводится информация из параметров arg1 … argn согласно формату, заданному аргументом fmt . В случае процедуры printf эта строка затем копируется в stdout. Процедура fprintf  направляет выходную строку в файл outf.

Для каждого из аргументов arg1 … argn должна быть задана своя спецификация формата, которая указывает тип соответствующего аргумента и способ его преобразования в выходную последовательность символов ASCII.

         Рассмотрим пример, демонстрирующий использование формата процедуры printf в двух простых случаях:

int iarg = 34;

     …

printf (“Hello, world!\n”);

printf (“Значение переменной iarg равно %d\n”, iarg);

Результат:

Hello, world!

Значение переменной iarg равно 34


Возможные типы спецификаций (кодов) формата:

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.