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

Функции построчного ввода:

      char *gets (char *строка); - функция принимает байты со стандартного потока ввода stdin и размещает их по адресу, на который ссылается указатель строка. Прием символов завершается после считывания символа ’\n’ (нажатие ENTER), а сам этот символ преобразуется в ’\0’. Необходимо зарезервировать место для принимаемой строки.

 

      char *fgets (char *строка, int колич_символов, FILE *имя_указателя); - функция принимает байты из открытого файла, на который ссылается указатель имя_указателя и размещает их по адресу, заданному указателем строка. Прием байтов завершается после получения колич_символов или получения символа ’\n’. Сам символ ’\n’ передается в строку. Последним символом в обоих случаях является ’\0’.

 

 

ВНИМАНИЕ

 

Перед началом использования необходимо зарезервировать место для строки.

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

 

 

Пример:

                  FILE *fp;

                  char s[100];

                  fp=fopen (“dat.txt”,”r”);

                  fgets (s, 20, fp);

 

 

Пример: get.c  ввод строковых данных с клавиатуры с помощью функции gets()

#include <stdio.h>

char input[257];

int main( void )

{

    puts("Enter some text, then press Enter: ");

    gets(input);

    printf("You entered: %s\n", input);

    return 0;

}

 

 

Результат:

                  Enter some text, then press Enter:

                  This is a test

                  You entered: This is a test

 

 

 

 

Функции построчного вывода в случае успеха возвращают код последнего записанного в файл символа строки и EOF - в случае ошибки.

 

Функции построчного вывода:

      int puts (char *строка); - функция помещает строку символов, на которую ссылается указатель строка, в стандартный поток вывода stdout.

 

      int fputs (char *строка, FILE *имя_указателя); - функция помещает строку символов, на которую ссылается указатель строка, в открытый файл, на который ссылается указатель имя_указателя.

 

 

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

Используйте функцию puts() вместо printf(), если необходимо отобразить текстовое сообщение без вывода каких-либо значений.

 

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

Не используйте спецификации ввода в функции puts().

 

 

Пример: put.c  отображение текста на экране с помощью функции puts()

#include <stdio.h>

char *message1 = "C";

char *message2 = "is the";

char *message3 = "best";

char *message4 = "programming";

char *message5 = "language!!";

int main( void )

{

   puts(message1);

   puts(message2);

   puts(message3);

   puts(message4);

   puts(message5);

   return 0;

}

 

 

Результат:

                  C

                  is the

                  best

                  programming

                  language!

 

 

13.3.3. Функции блокового ввода-вывода

 

 

Функции блокового ввода-вывода также называют функциями прямого ввода-вывода.

 

Функции fread() и fwrite() позволяют выполнить перенос блока байтов (записей) между файлом и программой.

 

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

 

Формат:

       int fread (void *имя_указателя1, int размер, int количество, FILE *имя_указателя2);

 

Эта функция считывает количество элементов размером размер байт каждый в область памяти, определяемую указателем имя_указателя1, из открытого файла, на который ссылается указатель имя_указателя2. Функция возвращает число прочитанных байтов и EOF – в противном случае.

 

Формат:

       int fwrite (void *имя_указателя1, int размер, int количество, FILE *имя_указателя2);

Эта функция записывает количество элементов размером размер байт каждый из области памяти, определяемую указателем имя_указателя1, в открытый файл, описываемый переменной типа FILE, на которую указывает указатель имя_указателя2.

 

Пример: считывание целого числа из файла

                  int num;

                  FILE *fp;

                  fp=fopen (“dat”,”r”);

                  . . .

                  fread (&num, sizeof (int), 1, fp);

 

Также функции fread() и fwrite() могут использоваться для записи и чтения пользовательских типов.

 

Пример:

                  FILE *fp;

                  fp= fopen (“dat”,”r”);

                  struct st1

                  {

                        float b;

                        char name[80];

                  } cust;

                  fread (&cust, sizeof (struct st1), 1, fp);

 

 

Пример: direct.c  использование функций fwrite() и fread() для блочного ввода-вывода

#include <stdlib.h>

#include <stdio.h>

#define SIZE 20

int main( void )

{

   int count, array1[SIZE], array2[SIZE];

   FILE *fp;

   for (count = 0; count < SIZE; count++)

       array1[count] = 2 * count;

   if ( (fp = fopen("direct.txt", "wb")) == NULL)

   {

       fprintf(stderr, "Error opening file.");

       exit(1);

   }

      if (fwrite(array1, sizeof(int), SIZE, fp) != SIZE)

   {

       fprintf(stderr, "Error writing to file.");

       exit(1);

   }

   fclose(fp);

   if ( (fp = fopen("direct.txt", "rb")) == NULL)

   {

       fprintf(stderr, "Error opening file.");

       exit(1);

   }

   if (fread(array2, sizeof(int), SIZE, fp) != SIZE)

   {

       fprintf(stderr, "Error reading file.");

       exit(1);

   }

   fclose(fp);

   for (count = 0; count < SIZE; count++)

       printf("%d\t%d\n", array1[count], array2[count]);

   return 0;

}

 

 

Результат:

                  0        0

                  2        2

                  4        4

                  6        6

                  8        8

                  10      10

                  12      12

                  14      14

                  16      16

                  18      18

                  20      20

                  22      22

                  24      24

                  26      26

                  28      28

                  30      30

                  32      32

                  34      34

                  36      36

                  38      38

 

 

Также при блоковом вводе-выводе могут использоваться функции getw() и putw().

 

Формат:

            int getw (FILE *имя_указателя); - возвращает число int, считанное из открытого файла

 

            putw (int число, FILE *имя_указателя); - записывает число в открытый файл, на который ссылается указатель имя_указателя.

 

Пример:

                  int num;

                  FILE *fp;

                  fp=fopen (“dat”,”r”);

                  num=getw(fp);

 

 

13.3.4. Функции форматированного ввода-вывода

 

 

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

 

Функции форматированного ввода-вывода являются функциями с переменным числом аргументов, первым из которых всегда является строка, задающая формат преобразования информации, которая состоит из следующих полей:

 

       %[флаги][ширина][.точность][модификаторы]<тип>

 

Флаги: «+», «-», «#», пробел.

 

Модификаторы: «F», «N», «h» «l», , «L».

 

Наиболее употребляемые управляющие последовательности указаны в таблице 3.

 

Таблица 3

Последовательность

Значение

\a

Звуковой сигнал (предупреждение)

\b

Возврат на один символ назад

\f

Прогон страницы

\n

Перевод строки

\r

Возврат каретки

\t

Горизонтальная табуляция

\v

Вертикальная табуляция

\\

Обратная косая черта

\?

Знак вопроса

\’

Одинарная кавычка

\”

Двойная кавычка

Начало или конец текстовой строки

 

Наиболее часто используемые спецификации ввода указаны в таблице 4.

 

Таблица 4

Спецификация

Значение

Типы выводимых

переменных

%c

Одиночный символ

char

%d

Десятичное целое число со знаком

int, short

%ld

Десятичное длинное целое число со знаком

long

%f

Десятичное число с плавающей точкой

float

%s

Строка символов

массивы типа char

%u

Десятичное целое число без знака

unsigned int, unsigned short

%lu

Десятичное длинное целое число без знака

unsigned long

 

 

 

Функции ввода:

        fscanf (); - вводит из заданного потока

        sscanf (); - вводит из строки символов Си

        scanf (); - вводит из стандартного потока ввода stdin

 

Функции вывода:

        printf (); - выводит в стандартный поток вывода stdout

        vprintf (); - аналогично предыдущей функции

        fprintf (); - выводит в заданный поток

        vfprintf (); - аналогично предыдущей функции

        sprintf (); - выводит в строку символов Си

        vsprintf (); - аналогично предыдущей функции

 

 

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

Обязательно используйте символ конца строки при выводе нескольких строк информации отдельными функциями printf().

 

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

Не пытайтесь выводить несколько строк текста одним вызовом функции printf(). В большинстве случаев удобно вывести несколько строк несколькими операторами, чем обходиться одним вызовом функции с несколькими символами конца строки «\n».

 

 

Пример:

               printf (“Это символ: %c, \nЭто число: %d\nЭто число с плав. \

                  точкой: %f\n”, ‘z’, 123, 456.789);

 

Результат:

                  Это символ: z

                  Это число: 123

                  Это число с плав. точкой: 456.789

 

 

ПРИМЕЧАНИЕ

В предыдущем примере можно заметить, что строка формата в функции printf() переносится на следующую строку. В конце первой строки кода косая черта «\» указывает, что строка формата продолжается в следующей строке кода. Компилятор воспринимает обе части строки формата как единое целое.

 

 

Пример:

               #include <stdio.h>

                  int main (void)

                  {

                        char symb=’S’;

                        int i=25;

                   printf (“Это пример вывода\n“);

                        printf (“Символ: %c\n Число: %d\n“, symb, i);

                        return 0;

                  }

 

Результат:

              Это пример вывода

                 Символ: S

                 Число: 25

 

 

Пример: fprintf.c  эквивалентность форматированного ввода в файл и в поток stdout

#include <stdlib.h>

#include <stdio.h>

void clear_kb(void);

int main( void )

{

    FILE *fp;

    float data[5];

    int count;

    char filename[20];

    puts("Enter 5 floating-point numerical values.");

    for (count = 0; count < 5; count++)

        scanf("%f", &data[count]);

    clear_kb();

    puts("Enter a name for the file.");

    gets(filename);

    if ( (fp = fopen(filename, "w")) == NULL)

    {

        fprintf(stderr, "Error opening file %s.", filename);

        exit(1);

    }

    for (count = 0; count < 5; count++)

    {

        fprintf(fp, "\ndata[%d] = %f", count, data[count]);

        fprintf(stdout, "\ndata[%d] = %f", count, data[count]);

    }

    fclose(fp);

    printf("\n");

    return 0;

}

void clear_kb(void)

{

    char junk[80];

    gets(junk);

}

 

 

Результат:

                    Enter 5 floating-point numerical values.

                    3.14159

                    9.99

                    1.50

                    3.

                    1000.0001

                    Enter a name for the file.

                    numbers.txt

 

                    data[0] = 3.141590

                    data[1] = 9.990000

                    data[2] = 1.500000

                    data[3] = 3.000000

                    data[4] = 1000.000122

 

 

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

Используйте функции printf() и puts() в связке со scanf(). Сначала выведите сообщение о том, какие данные должен ввести пользователь, а затем введите эти данные функцией scanf().

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

Не забывайте использовать знак операции взятия адреса «&» перед переменными в функции scanf().

 

 

Пример:

                  #include <stdio.h>

                  int main (void)

                  {

                        int num;

                        scanf (“%d“, &num);

                   printf (“\nВы ввели число: %d“, num);

                        return 0;

                  }

 

Результат:

               // введено число 17 с клавиатуры

               Вы ввели число: 17

 

 

Пример: scanit.c  ввод числовых данных с использованием функции scanf()

#include <stdio.h>

#define QUIT 4

int get_menu_choice( void );

int main( void )

{

    int   choice    = 0;

    int   int_var   = 0;

    float float_var = 0.0;

    unsigned unsigned_var = 0;

    while (choice != QUIT)

    {

        choice = get_menu_choice();

        if (choice == 1)

        {

            puts("\nEnter a signed decimal integer (i.e. -123)");

            scanf("%d", &int_var);

        }

        if (choice == 2)

        {

            puts("\nEnter a decimal floating-point number(e.g. 1.23)");

            scanf("%f", &float_var);

        }

        if (choice == 3)

        {

             puts("\nEnter an unsigned decimal integer (e.g. 123)" );

             scanf( "%u", &unsigned_var );

         }

    }

    printf("\nYour values are: int: %d  float: %f  unsigned: %u \n", int_var, float_var, unsigned_var );

   return 0;

}

int get_menu_choice( void )

{

    int selection = 0;

    do

    {

        puts( "\n1 - Get a signed decimal integer" );

        puts( "2 - Get a decimal floating-point number" );

        puts( "3 - Get an unsigned decimal integer" );

        puts( "4 - Quit" );

        puts( "\nEnter a selection:" );

        scanf( "%d", &selection );

     }while ( selection < 1 || selection > 4 );

     return selection;

}

 

 

 

Пример: input.c  ввод числовой и текстовой информации с помощью функции scanf()

#include <stdio.h>

char lname[257], fname[257];

int count, id_num;

int main( void )

{

    puts("Enter last name, first name, ID number separated");

    puts("by spaces, then press Enter.");

    count = scanf("%s%s%d", lname, fname, &id_num);

    printf("%d items entered: %s %s %d \n", count, fname, lname, id_num);

    return 0;

}

 

 

Результат:

                    Enter last name, first name, ID number separated

                    by spaces, then press Enter.

                    Corey Taylor 12345

                    3 items entered: Corey Taylor 12345

 

 

ВНИМАНИЕ

 

Пользуйтесь функцией scanf() с осторожностью. Если, например, ожидается ввод символа, а пользователь введет число, или если нужно число, а вводится символ, то программа может выдать пользователю весьма неожиданные результаты.

 

 

Пример: fscanf.c  чтение форматированных данных из файла с помощью функции fscanf()

#include <stdlib.h>

#include <stdio.h>

int main( void )

{

   float f1, f2, f3, f4, f5;

   FILE *fp;

    if ( (fp = fopen("INPUT.TXT", "r")) == NULL)

    {

        fprintf(stderr, "Error opening file.\n");

        exit(1);

    }

    fscanf(fp, "%f %f %f %f %f", &f1, &f2, &f3, &f4, &f5);

    printf("The values are %f, %f, %f, %f, and %f\n.", f1, f2, f3, f4, f5);

    fclose(fp);

    return 0;

}

 

 

Результат:

                    The values are 123.49997, 87.00999, 100.019997, 0.004560, and 1.0005000

 

 

ПРИМЕЧАНИЕ

Неточность машинного представления числа является причиной того, что выведенные значения отличаются от введенных на очень маленькие величины. Например, 100.2 выводится как 100.01999.

 

 

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

Используйте функции gets() и scanf() вместо fgets() и fscanf(), если ввод должен выполняться только из стандартного потока stdin.

 

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

Не забывайте избавляться от лишних символов в потоке ввода.

 

 

Пример: printer.c  вывод данных на принтер

#include <stdio.h>

int main( void )

{

    float f = 2.0134;

    fprintf(stdprn, "\n Это сообщение распечатается на принтере.\r\n");

    fprintf(stdprn, "And now some numbers:\r\n");

    fprintf(stdprn, "The square of %f is %f.", f, f*f);

    fprintf(stdprn, "\f");

    return 0;

}

 

 

Результат:

                    Следующие строки  распечатаются на принтере

                    Цифры также выведутся на принтер:

                    Квадрат 2.013400 это 4.053780

 

 

ПРИМЕЧАНИЕ

Чтобы использовать поток stdprn, необходимо отказаться от совместимости с ANSI в вашем компиляторе. Обратитесь к документации компилятора за более подробной информацией. Поскольку поток stdprn не определен в стандарте ANSI, не каждый компилятор его поддерживает.

 

 

Пример: escape.c  использование специальных символов в функции printf()

#include <stdio.h>

#define QUIT  3

int  get_menu_choice( void );

void print_report( void );

int main( void )

{

    int choice = 0;

    while (choice != QUIT)

    {

       choice = get_menu_choice();

       if (choice == 1)

           printf("\nBeeping the computer\a\a\a" );

       else

       {

           if (choice == 2)

               print_report();

       }

    }

    printf("You chose to quit!\n");

    return 0;

}

int get_menu_choice( void )

{

    int selection = 0;

    do

    {

        printf( "\n" );

        printf( "\n1 - Beep Computer" );

        printf( "\n2 - Display Report");

        printf( "\n3 - Quit");

        printf( "\n" );

        printf( "\nEnter a selection:" );

        scanf( "%d", &selection );

     }while ( selection < 1 || selection > 3 );

     return selection;

}

void print_report( void )

{

     printf( "\nSAMPLE REPORT" );

     printf( "\n\nSequence\tMeaning" );

     printf( "\n=========\t=======" );

     printf( "\n\\a\t\tbell (alert)" );

     printf( "\n\\b\t\tbackspace" );

     printf( "\n...\t\t...");

}

 

 

 

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

Используйте функцию fprintf() при написании ваших программ, посылающих целевой вывод в поток stdoutstderrstdprn.

 

 

Пример: num.c  ввод числовых значений с помощью функции printf()

#include <stdio.h>

int a = 2, b = 10, c = 50;

float f = 1.05, g = 25.5, h = -0.1;

int main( void )

{

    printf("\nDecimal values without tabs: %d %d %d", a, b, c);

    printf("\nDecimal values with tabs: \t%d \t%d \t%d", a, b, c);

    printf("\nThree floats on 1 line: \t%f\t%f\t%f", f, g, h);

    printf("\nThree floats on 3 lines: \n\t%f\n\t%f\n\t%f", f, g, h);

    printf("\nThe rate is %f%%", f);

    printf("\nThe result of %f/%f = %f\n", g, f, g / f);

    return 0;

}

 

Результат:

                  Decimal values without tabs: 2 10 50

                  Decimal values with tabs:           2          10        50

                  Three floats on 1 line:                 1.050000         25.500000       -0.100000

                  Three floats on 3 line:

                  1.050000

                  25.500000

                  -0.100000

                  The rate is 1.050000%

                  The result of 25.500000/1.050000 = 24.285715

 

 

СОВЕТ

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

 

 

13.4. Последовательный и прямой доступ в поток

 

 

Операции чтения и записи для потока начинается с текущей позиции потока, определяемой указателем потока. Начальная позиция указателя потока устанавливается при открытии потока и может указывать на начало в режиме доступа «r» и «w», и на конец - в режиме «а».

 

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

 

Указатель потока можно позиционировать на любое место в потоке, т.е. осуществлять прямой доступ

 

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

        ftell(); или fgetpos(); - определяют текущую позицию указателя потока

        fseek(); или fsetpos(); - устанавливают указатель потока в заданную позицию

        rewind(); - устанавливает указатель потока в начальную позицию

 

Формат:

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

 

Формат:

            int fseek (FILE *имя_указателя, long колич_байт, int из_положения);

 

где

имя_указателя – это указатель, ссылающийся на соответствующий файл.

 

Данная функция сдвигает указатель потока на число байт, равное аргументу колич_байт от точки отсчета, задаваемой аргументом из_положения.

 

 

ПРИМЕЧАНИЕ

Если параметр колич_байт>0, то указатель потока сдвигается в сторону конца файла.

Если параметр колич_байт<0, то указатель потока сдвигается в сторону начала файла.

 

 

Аргумент из_положения – это один из макросов, определенных в «stdio.h», определяющих точку отсчета для сдвига и может принимать одно из следующих значений:

        SEEK_SET - начало потока

        SEEK_CUR - текущая позиция потока

        SEEK_END - конец потока).

           

В случае успеха функция fseek() возвращает ноль, а при ошибке – EOF.

 

Пример:

                  FILE *fp;

                  long n;

                  fp= fopen (“dat”,”r”);

                  n=14;

                  fseek (fp, n, SEEK_SET);

                  fseek (fp, 0L, SEEK_SET);

                  fseek (fp, -n, SEEK_END);         // n-й элемент с конца

 

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

                  int readbytes (FILE *fp, long pos, int n, char *save)

                  {

                        int num=-1;

                        if (fseek (fp, pos, SEEK_SET)==0)

                                   num=fread (save, 1, n, fp);

                        return num;

                  }

 

Для определения текущей позиции потока используется функция ftell().

 

Формат:

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

 

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

 

При использовании fseek() и ftell() следует учитывать преобразование символа ‘\n’ в два символа – «возврат каретки» и «перевод строки». Поэтому, задавая значения параметров функции fseek() или интерпретируя полученные результаты от ftell() следует помнить о дополнительных байтах в файле.

 

Например, запись 10 строк по 20 символов в каждой в поток, открытый в текстовом режиме, даст файл общей длинной (10*20)+10=210 байт (вместо предполагаемых 200 байт), а обращение «fseek(fp, 42, SEEK_SET);» установит указатель потока на конец 2-й строки, а не на начало 3-й.

 

 

ВНИМАНИЕ

 

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

 

 

Пример: ftell.c  использование функций rewind() и  ftell()

#include <stdlib.h>

#include <stdio.h>

#define BUFLEN 6

char msg[] = "abcdefghijklmnopqrstuvwxyz";

int main( void )

{

    FILE *fp;

    char buf[BUFLEN];

    if ( (fp = fopen("TEXT.TXT", "w")) == NULL)

    {

        fprintf(stderr, "Error opening file.");

        exit(1);

    }

    if (fputs(msg, fp) == EOF)

    {

        fprintf(stderr, "Error writing to file.");

        exit(1);

    }

    fclose(fp);

    if ( (fp = fopen("text.txt", "r")) == NULL)

    {

        fprintf(stderr, "Error opening file.");

        exit(1);

    }

    printf("\nImmediately after opening, position = %ld", ftell(fp));

    fgets(buf, BUFLEN, fp);

    printf("\nAfter reading in %s, position = %ld", buf, ftell(fp));

    fgets(buf, BUFLEN, fp);

    printf("\n\nThe next 5 characters are %s, and position now = %ld",

            buf, ftell(fp));

    rewind(fp);

 

    printf("\n\nAfter rewinding, the position is back at %ld",

            ftell(fp));

    fgets(buf, BUFLEN, fp);

    printf("\nand reading starts at the beginning again: %s\n", buf);

    fclose(fp);

    return 0;

}

 

Скачать архив [ftell.c, ftell.exe и text.txt]

 

Результат:

                    Immediately after opening, position = 0

                    After reading in abcde, position = 5

 

                    The next 5 characters are fhig, and position now = 10

                   

                    After rewinding, the position is back at 0

                    and reading starts at the beginning again: abcde

 

 

Пример: fseek.c  произвольный доступ к файлу при помощи fseek()

#include <stdlib.h>

#include <stdio.h>

#define MAX 50

int main( void )

{

    FILE *fp;

    int data, count, array[MAX];

    long offset;

    for (count = 0; count < MAX; count++)

        array[count] = count * 10;

    if ( (fp = fopen("random.dat", "wb")) == NULL)

    {

        fprintf(stderr, "\nError opening file.");

        exit(1);

    }

    if ( (fwrite(array, sizeof(int), MAX, fp)) != MAX)

    {

        fprintf(stderr, "\nError writing data to file.");

        exit(1);

    }

    fclose(fp);

    if ( (fp = fopen("RANDOM.DAT", "rb")) == NULL)

    {

        fprintf(stderr, "\nError opening file.");

        exit(1);

    }

    while (1)

    {

        printf("\nEnter element to read, 0-%d, -1 to quit: ",MAX-1);

        scanf("%ld", &offset);

        if (offset < 0)

            break;

        else if (offset > MAX-1)

            continue;

        if ( (fseek(fp, (offset*sizeof(int)), SEEK_SET)) != 0)

        {

            fprintf(stderr, "\nError using fseek().");

            exit(1);

        }

        fread(&data, sizeof(int), 1, fp);

        printf("\nElement %ld has value %d.", offset, data);

    }

    fclose(fp);

    return 0;

}

 

 

Результат:

                    Enter element to read, 0-49, -1 to quit: 5

 

                    Element 5  has value 50.

                    Enter element to read, 0-49, -1 to quit: 6

 

                    Element 6  has value 60.

                    Enter element to read, 0-49, -1 to quit: 49

 

                    Element 49  has value 490.

                    Enter element to read, 0-49, -1 to quit: 1

 

                    Element 1  has value 10.

                    Enter element to read, 0-49, -1 to quit: 0

 

                    Element 0  has value 0.

                    Enter element to read, 0-49, -1 to quit: -1

                   

                   

13.5. Управление буферизацией

 

 

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

 

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

 

При операции записи буфер выгружается (содержание буфера помещается в соответствующий поток) в следующих случаях:

      Буфер заполнен

      Закрывается связанный с ним поток

      При успешном завершении программы

 

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

 

Размер внутреннего буфера библиотечных функций составляет 512 байт для регулярных файлов и 128 байт – для стандартных файлов. Буферизацией ввода-вывода управляют функции setbuf() и setvbuf(), позволяющие либо отключить буферизацию полностью, либоиспользовать в качестве буфера область памяти прикладной программы (последнее, дает возможность существенно сократить объем памяти, необходимый программе при выполнении). Эти функции содержатся в «stdio.h».

 

Буферы, предоставленные ОС, пользователю не доступны, а с буферами, распределенные функциями  setbuf() и setvbuf(), можно работать как с обычными переменными.

 

Формат: