Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по вводу-выводу.doc
Скачиваний:
6
Добавлен:
18.09.2019
Размер:
583.17 Кб
Скачать

Int open (const char *имя_файла, int доступ);

 

Данная функция открывает файл для записи/чтения и возвращает дескриптор файла, который можно присвоить целой переменной и использовать ее для ссылки на файл. Функция в случае успеха возвращает дескриптор файла или «-1» при ошибке.

 

Аргумент доступ задает тип допустимых операций для файла и может принимать одно из находящихся в файле «fcntl.h» константных значений:

           O_APPEND - файл открывается для добавления в конец

           O_BINARY - файл открывается для добавления в конец в двоичном режиме

           O_CREAT - создается и открывается новый файл

           O_RDONLY - создается и открывается новый файл только для чтения

           O_RDWR - создается и открывается новый файл для чтения и записи

           O_TEXT - создается и открывается новый файл в текстовом режиме

           O_TRUNC - открывается существующий файл, а его содержимое удаляется

           O_WRONLY - открывается только для записи существующий файл, а его содержимое удаляется

 

 

ПРИМЕЧАНИЕ

Если нужно задать более одной константы, то они связываются последовательно с помощью символа «|».

 

 

Пример:

                  int handle;

                  handle=open (“file.bat”,O_CREAT | O_WRONLY);

 

 

13.6.2. Закрытие файла

 

 

Закрытие ранее открытого файла производится с помощью функции close().

 

Формат:

            int close (int handle);

 

Данная функция в случае успеха возвращает ноль и «-1» - при ошибке.

 

Пример:

                  #include <stdio.h>

                  #include <io.h>

                  #include <fcntl.h>

                  main ()

                  {

                        int handle;

                        . . .

                        if ((handle=open (“file”, O_RDONLY)==-1)

                                   fprintf (stderr, “Невозможно открыть файл!”);

                        . . .

                        close (handle);

                  }

 

 

13.7. Переопределение файлов и потоков

 

 

С началом выполнения любой программы автоматически открываются пять файлов (потоков), с которыми связаны дескрипторы.

 

Таблица 2

Дескриптор

Поток (файл)

0

stdin

1

stdout

2

stderr

3

stdaux

4

stdprn

 

С помощью этих дескрипторов программа может иметь доступ к стандартным файлам. Можно определить и дескрипторы, связанные с любымпотоком, с помощью функции fileno() из библиотеки «stdio.h».

                                                                                                    

Формат:

            int fileno (FILE *имя_указателя);

 

Данная функция возвращает дескриптор файла, на который ссылается указатель *имя_указателя.

 

Если поток имеет несколько дескрипторов, то возвращается тот, который связывается с потоком при первичном открытии файлаОдному и тому же файлу можно назначить несколько дескрипторов с помощью функций dup() и dup2(). Обычно они используются для переадресации обмена со стандартными файлами ввода-вывода.

           

Формат:

            int dup (int дескриптор);

 

Данная функция назначает новый дескриптор файлу с дескриптором дескриптор. В случае успеха функция возвращает новый дескриптор, а при ошибке – «-1».

 

 

НЕ РЕКОМЕНДУЕТСЯ

Не пытайтесь перенаправить поток stderr.

Не используйте поток stderr для каких либо других целей, кроме вывода предупреждений и сообщений об ошибках.

 

 

Во внутренней таблице открытых файлов системы отыскивается новый свободный элемент, в который копируется элемент внутренней таблицы с порядковым номером дескриптор. В результате в таблице появится два элемента, которые ссылаются на один и тот же файл.

 

Пример: назначение нового дескриптора потоку

                  #include <stdio.h>

                  #include <io.h>

                  int newhandle (FILE *fp)

                  {

                        int new;

                        if ((new=dup (fileno (fp)))==-1)

                                   printf (“нельзя назначить новый дескриптор потоку\n”);

                        return new;

                  }

                  main ()

                  {

                        FILE *fptr;

                       int newhndl;

                        . . .

                        newhndl=newhandle(fptr)

                  }

 

Формат:

            int dup2 (int стар_дескриптор, int нов_дескриптор);

 

Данная функция копирует информацию о файле с дескриптором стар_дескриптор в строку таблицы файлов с номером нов_дескриптор. Если эта строка таблицы была отведена под другой файл или устройство, то они закрываются. В случае успеха функция возвращает ноль, а приошибке – «-1».

 

 

ПРИМЕЧАНИЕ

Помните, что перенаправление потоков stdin и stdout – это возможность операционной системы, а не самого языка Си. Тем не менее, это еще одно свидетельство гибкости и удобства потоков ввода-вывода. Более подробную информацию о перенаправлении можно найти в документации операционной системы.

 

 

Пример:

                  #include <stdio.h>

                  #include <io.h>

                  #include <fcntl.h>

                  main ()

                  {

                        int e;

                        e=open (“file.out”, O_CREAT | O_WRONLY);

                        dup2 (e, 1);                 // переназначит стандартный вывод с дескриптором 1 (stdin) в «file.out»

                        printf (“Пример\n”);

                  }

Результат: слово “Пример” в файле «file.out» без вывода на экран

 

 

13.8. функции чтения и записи данных

 

 

К функциям чтения и записи данных относятся две функции read() и write() из библиотеки «io.h».

 

Формат:

            int read (int дескриптор, void *имя_указателя, unsigned колич);

 

Данная функция выполняет чтение колич-байт из открытого файла с дескриптором дескриптор и размещенного по адресу, на который ссылается указатель *имя_указателя. В случае успеха функция возвращает прочитанное число байтов, а при ошибке – «-1».

 

Формат:

            int write (int дескриптор, void *имя_указателя, unsigned колич);

 

Данная функция выполняет запись колич-байт в открытый файл с дескриптором дескриптор и размещенного по адресу, на который ссылается указатель *имя_указателя. В случае успеха функция возвращает записанное число байтов, а при ошибке – «-1».

 

Функция lseek() позволяет установить текущий указатель чтения/записи. Функция tell() позволяет определить текущую позицию указателя.

 

 

ВНИМАНИЕ

 

Функции lseek() и tell() нельзя применять к устройствам.

 

 

Пример:

                  char string[512]=”Тестовая строка”;

                  . . .

                  handle=creat (“DATA”, S_IREAD | S_IWRITE);          // S_IREAD и S_IWRITE находятся в «sys\stat.h»

                  write (handle, string, sizeof (string));

                  read (handle, string, 512);

                  . . .

                  close (handle);

 

 

13.9. Ввод-вывод для консоли и портов

 

 

С помощью функций, прототипы которых находятся в библиотеке «stdio.h», нельзя выполнить неотображенный на экран ввод символов,определить нажатие специальной клавиши и т.д. Для выполнения таких действий используются функции ввода-вывода для консоли ипортов, прототипы которых находятся в библиотеке «conio.h».

 

Функции для работы с консолью:

        cgets () – вводит строку с консоли

        cputs () – выводит строку в консоль

        cscanf () – вводит форматированные данные с консоли

        cprintf () – выводит форматированные данные в консоль

        getch () – вводит символ с консоль

        getc () – выводит символ с консоли и отображает его на экране

        ungetch () – «возвращает» прочитанный символ на консоль (записывает непосредственно в буфер клавиатуры символ, который будет прочитан при выполнении следующей операции чтения)

        putch () – выводит символ на консоль

        kbhit () – проверяет, была ли нажата клавиша на клавиатуре

 

Функции для работы с портами:

        inp () – читает один байт из порта

        inpw () – читает два байта из порта

        outp () – записывает один байт в порт

        outpw () – записывает два байта в порт

 

 

ВНИМАНИЕ

 

Для консоли и порта нет функций открывающих или закрывающих, т.к. консоль и порты не закрываются и не открываются во время ввода-вывода.

 

 

Для организации интерфейса с пользователем, при котором нажатие клавиши вызывает мгновенную реакцию программы без отображения введенного символа на экране, полезна функция getch().

 

Формат:

            int getch (void);

 

Данная функция выполняет ввод с клавиатуры одного символа и не выполняет эхо ввода на экран. В случае успеха функция возвращаетвведенный символ.

 

 

ПРИМЕЧАНИЕ

Для чтения функциональных клавиш функция должна вызываться дважды; в этом случае первый вызов возвращает ноль, а второй – код нажатой клавиши.

 

 

Пример: 

                  #include <stdio.h>

                  #include <conio.h>

                  main ()

                  {

                        int ch;

                        do

                        {

                                   puts (“Нажмите клавишу\n”);

                                   if (!(ch=getch()))

                                   {

                                               ch=getch();

                                               printf (“Специальная клавиша (Код %u)\n”, ch);

                                   }

                                   else printf (“Символьная клавиша %c (Код %u)\n”, ch, ch);

                                   puts (“Продолжить? (y/n)”);

                        }

                        while ((ch=getch())==’y’ || ch==’n’);

                        return 0;

                  }

 

Результат:

               Нажмите клавишу

                  // нажат 0

                  Символьная клавиша 0 (Код 48)

                  Продолжить? (y/n)

               Нажмите клавишу

                  // нажат F1

                  Символьная клавиша  (Код 59)

                  Продолжить? (y/n)