Главная страница
Навигация по странице:

  • Продолжение табл. 1.11. 1

  • 1. 11. Лабораторная работа 11


    Скачать 169.5 Kb.
    Название1. 11. Лабораторная работа 11
    Дата20.09.2022
    Размер169.5 Kb.
    Формат файлаdoc
    Имя файлаLab11_4.doc
    ТипПрактикум
    #688060

    С этим файлом связано 1 файл(ов). Среди них: lab_03.pdf.
    Показать все связанные файлы

    Практикум по программированию на языке Си



    1.11.Лабораторная работа 11


    Работа с файлами

    1.11.1.Постановка задачи


    Имеется текстовый файл, содержащий произвольное количество строк. Длина каждой строки не превосходит 255 символов. Необходимо выполнить заданную обработку файла.

    1.11.2.Варианты заданий


    Варианты заданий приведены в табл. 1.11. 1
    Таблица 1.11. 1

    N

    Задание

    1

    В каждой строке исходного файла имеется произвольное количество чисел, записанных в форме f. Количество чисел в строке не превосходит 10. Сформировать новый файл, содержащий нормализованные числа исходного файла. Каждая строка файла нормализуется отдельно путем деления ее элементов на значение максимального элемента строки.

    2

    В каждой строке исходного файла имеется произвольное количество чисел, записанных в форме f. Сформировать новый файл, дописав в начало каждой строки исходного файла сумму ее элементов.

    3

    В каждой строке исходного файла имеется произвольное количество чисел, записанных в форме f. Сформировать новый файл, дописав в начало каждой строки исходного файла количество, содержащихся в ней чисел.

    4

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

    5

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

    6

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

    СТРОКА ПРОИЗВЕДЕНИЕ

    <номер строки> <вычисленное произведение>


    7

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

    8

    Имеется текстовый файл, содержащий не более 100 строк. Выполнить сортировку строк файла в прямом лексикографическом порядке. Результаты сортировки записать в новый файл.


    Продолжение табл. 1.11. 1


    N

    Задание

    9


    В файле хранится числовая матрица. В первой строке файла записаны два числа: количество строк (N <= 20) и столбцов матрицы (M<=5), а затем сама матрица. Вычислить для каждого столбца сумму его элементов. Результаты вычислений должны быть записаны в конец исходного файла в виде таблицы следующего вида:

    СТОЛБЕЦ СУММА

    <номер столбца> <вычисленная сумма>


    10

    Имеется текстовый файл, содержащий не более 100 строк. Выполнить сортировку строк файла в обратном лексикографическом порядке. Результаты сортировки записать в новый файл.

    11

    Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить сумму содержащихся в ней чисел, а затем выполнить сортировку строк файла в порядке возрастания суммы. Результаты сортировки записать в новый файл.

    12

    Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить сумму содержащихся в ней чисел, а затем выполнить сортировку строк файла в порядке убывания суммы. Результаты сортировки записать в новый файл.

    13

    В каждой строке записано произвольное количество чисел, записанных в форме f. Сформировать новый файл, дописав в конец каждой строки исходного файла значение ее максимального элемента.

    14

    В каждой строке записано произвольное количество чисел, записанных в форме f. Сформировать новый файл, дописав в начало каждой строки исходного файла значение минимального элемента этой строки.

    15

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

    СТРОКА СУММА ПОЛОЖИТЕЛЬНЫХ ЭЛЕМЕНТОВ

    <номер строки> <вычисленная сумма>

    16

    В каждой строке записано произвольное количество чисел, записанных в форме f. Сформировать новый файл, дописав в каждую строку исходного файла сумму ее положительных элементов.

    17

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

    Окончание табл.1.11. 1


    18

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




    19

    В каждой строке записано произвольное количество чисел, записанных в форме f. Сформировать новый файл, переписав в него только те строки, в которых отсутствуют положительные числа.




    20

    В каждой строке файла имеется произвольное количество чисел, записанных в форме f. Сформировать новый файл, содержащий нормализованные числа исходного файла. Каждая строка нормализуется путем деления ее элементов на полусумму значений максимального и минимального элемента строки.

    21

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

    22

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

    23

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

    24

    Дан текстовый файл. Записать в новый текстовый файл все строки исходного файла, которые в качестве фрагмента содержат строку Str.

    25

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

    26

    В файле хранится числовая матрица. В первой строке файла записаны два числа: количество строк(N <= 10) и столбцов матрицы(M <= 15), а затем - сама матрица. Для каждого столбца матрицы вычислить корень квадратный из суммы квадратов ее элементов. Результаты вычислений необходимо записать в новый файл.



    1.11.3.Методические указания по выполнению лабораторной работы


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

    1. Требуемую обработку следует оформить в виде функции пользователя. Входной и выходной файлы в эту функцию целесообразно передавать с помощью аппарата формальных и фактических параметров, а подготовительные файловые операции предпочтительнее выполнять в клиентском коде этой функции. К таким операциям относятся следующие операции: открытие и закрытие файла.

    2. В ряде задач в файле хранится числовая матрица. Это задачи 5 – 7, 9, 15, 17, 18, 22, 25 и 26. Первая строка файла в этих задачах содержит два числа, которые определяют количество строк и столбцов матрицы. Обработка файла может быть построена следующим образом. Вначале из файла читаются с помощью функции fscanf() два первых числа, которые записываются в две целочисленные переменные n и m. Затем следует организовать вложенные арифметические циклы.

    3. В задачах 8, 10 - 12 необходимо выполнить сортировку строк файла. Для выполнения сортировки можно воспользоваться любым способом. Например, можно использовать простейший способ – метод пузырьковой сортировки. В качестве примера ниже приводится функция для сортировки строк в порядке их возрастания (bibble).


    #define MAXLENGTH 128
    void bibble(char arr[][MAXLENGTH + 1], int n)

    {

    int i, j;

    char buf[MAXLENGTH + 1];

    for(i = 1; i < n; i++)

    {

    for(j = n - 1; j >=i; --j )

    {

    if(strcmp(arr[j - 1], arr[j]) < 0)

    {

    strcpy(buf, arr[j - 1]);

    strcpy(arr[j - 1], arr[j]);

    strcpy(arr[j], buf);

    }

    }

    }

    }

    1. В ряде задач в файле находится произвольное количество строк, каждая из которых содержит произвольное количество чисел. К таким задачам относятся задачи 1 – 3, 13, 14, 16, 19 – 21. В этом случае обработка может состоять из вложенных итерационных циклов. Во внешнем цикле можно читать очередную строку, а во внутреннем цикле выполнять обработку строки с помощью функции strtod().

    2. В процессе решения поставленной задачи следует продумать, какие структуры данных могут потребоваться для ее решения. В первую очередь, это относится к тем задачам, в которых в файле хранится матрица. В этих задачах необходимо выяснить требуется или нет при ее решении использовать двумерный массив. В ряде случаев необходимости в их применении нет. К числу таких задач относится, например задача 25. В этой задаче необходимо вычислить корень квадратный из суммы элементов строки числовой матрицы, хранящейся в текстовом файле. Здесь структура программы – вложенные арифметические циклы. Внутренний цикл должен выполнять суммирование квадратов элементов очередной строки, а внешний цикл – вычисляет корень квадратный из накопленной внутренним циклом суммы. Особенностью этой задачи является то положение, что прочитанное из файла число может сразу же быть обработано (просуммировано с квадратом) и необходимости в его хранении для последующей обработки нет. Совсем иначе дело обстоит при решении задачи 26. Здесь необходимо решить практически ту же задачу, что и в варианте 25, но применительно к столбцам матрицы. Здесь придется вначале прочитать весь файл в матрицу (двумерный числовой массив) и только затем приступить к его обработке.

    1.11.4.Справочные материалы


    При работе с внешними устройствами при программировании на языке Си следует использовать библиотечные функции. Библиотечные функции языка Си, предназначенные для работы с внешними устройствами можно разделить на две категории:

    • низкоуровневые функции,

    • потоковые функции.

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

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

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

    Понятие потока


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

    • конкретного типа внешнего устройства,

    • среды, в которой выполняется программа.

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

    • текстовые,

    • двоичные.
    Текстовый поток

    Текстовый поток – это последовательность символов, организованная в строки. Каждая строка должна заканчиваться символом новой строки: ‘\n’. Однако в конце последней строки этот символ не является обязательным. В зависимости от среды, в которой происходит выполнение программы, при использовании текстового потока может иметь место преобразование символов. Например, при записи в среде DOS или Windows символ ‘\n’ преобразуется в последовательность символов CRLF.

    Таким образом, при использовании текстового потока может и не иметь место однозначное соответствие между символами, которые записываются (читаются) и теми символами, которые хранятся на внешнем устройстве.

    Кроме того, при использовании текстового потока для чтения особым образом обрабатывается символ конца файла. В таблице кодов ASCII этот символ имеет код 0x1A.
    Двоичный поток

    Двоичный поток – это последовательность байтов, которая взаимно однозначно соответствует байтам на внешнем устройстве, причем никаких преобразований символов не происходит; отсутствуют символы, которые играют особую роль. Все символы обрабатываются одинаково. Количество символов, которые записываются (читаются) совпадает с количеством символов, хранящихся на внешнем устройстве.

    1.11.4.1.Файлы в языке СИ


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

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

    1.11.4.2.Указатель файла


    У каждого файла, связанного с потоком, имеется специальная управляющая структура, содержащая сведения о файле. Эта структура имеет тип FILE. Этот тип объявлен в заголовочном файле stdio.h. Для каждого файла, с которым должна работать программа должен существовать свой указатель файла. Указатель файла – это указатель на структуру типа FILE. Указатель файла представляет файл во всех операциях ввода – вывода..

    1.11.4.3.Функция fopen


    Объявление этой функции имеет следующий вид.

    #include

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

    Эта функция открывает поток и связывает с ним определенный файл. Первый параметр (filename) рассматриваемой функции определяет открываемый файл. Второй параметр функции (mode) задает режим, в котором должен быть открыт файл.

    В случае успеха функция вернет указатель типа FILE* на созданную структуру данных. Этот указатель может использоваться файловыми функциями для выполнения операций ввода – вывода. В случае возникновения ошибки функция fopen() вернет нулевой указатель.

    В следующем фрагменте программного кода функция используется для открытия файла с именем file1.txt в режиме записи. Предполагается, что файл находится в текущем каталоге (иначе необходимо указывать путь к каталогу). Во фрагменте используется обычный прием, который состоит в проверке значения, возвращаемого функцией fopen().

    FILE* fp;
    if((fp = fopen(“file1.txt”, “w”)) == NULL)
    {
    printf(“Не могу открыть файл file1.txt”);
    exit(1);
    }

    Возможные режимы открытия потоков представлены в таблице 1.11. 2.

    Таблица 1.11. 2.

    Режим

    Пояснение

    r

    Открыть текстовый поток и связать его с существующим файлом

    w

    Открыть текстовый поток и связать его с вновь созданным файлом

    a

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

    rb, wb и ab

    Отличаются соответственно от режимов r, w и a только тем, что открывают двоичный поток.

    r+, w+ и a+

    Отличаются соответственно от режимов r, w и a только тем, что поток открывается в режиме чтения / записи.

    r+b, w+b и a+b

    Отличаются соответственно от режимов rb, wb и ab только тем, что поток открываются в режиме чтения / записи.



    1.11.4.4.Функция fclose


    Объявление этой функции имеет следующий вид.

    #include

    int fсlose(FILE* stream);

    Функция fclose() закрывает поток stream. Перед закрытием потока все связанные с ним буферы сбрасываются. При успешном выполнении функция fclose() возвращает 0, а в случае ошибки – EOF.

    1.11.4.5.Функция feof


    Объявление рассматриваемой функции имеет следующий вид:

    #include

    int feof(FILE* stream);

    Функция feof() проверяет, достигнут ли конец файла при выполнении очередной операции чтения. Параметр stream является указателем на поток, с которым работает файл.

    Если указатель текущей позиции файла установлен на конец файла, то функция feof() вернет ненулевое значение, в противном случае возвращается нуль.

    1.11.4.6. Стандартные потоки


    В начале выполнения программы автоматически открываются три стандартных потока (см. таблицу 1.12. 3)

    Таблица 1.11. 3.

    Поток

    Файловый указатель

    Внешнее устройство

    Ввода

    stdin

    клавиатура

    Вывода

    stdout

    Экран дисплея

    Ошибок

    stderr

    Экран дисплея



    1.11.4.7.Классификация функций потокового ввода – вывода


    Все функции потокового ввода – вывода можно разделить на четыре категории:

    • форматированный ввод – вывод,

    • посимвольный ввод – вывод,

    • построковый ввод – вывод,

    • блоковый ввод – вывод.

    1.11.4.8.Форматированный файловый ввод – вывод


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

    • fprintf() – для записи в файл,

    • fsсanf() - для чтения из файла.

    Функция fprintf() объявлена следующим образом:

    #include

    int fpintf(FILE* stream, const char* format[, аргумент, …] );

    Рассматриваемая функция является обобщенным вариантом функции printf(). Здесь появился дополнительный параметр stream, которого нет в функции printf. Параметр stream является указателем на поток, который должен быть предварительно открыт функцией fopen().

    Функция fprintf() возвращает число выведенных символов или отрицательное число, если произошла ошибка вывода.

    Функция fscanf() объявлена следующим образом:

    #include

    int fscanf(FILE* stream, const char* format[, указатель, …] );

    Эта функция в свою очередь является обобщенным вариантом функции scanf(). Здесь также появился дополнительный параметр stream – указатель на поток.

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

    1.11.4.9.Построчный ввод – вывод


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

    • fputs(),

    • fgets().

    Функция fputs() объявлена следующим образом:

    #include

    int fputs(const char* s, FILE* stream);

    Функция fputs() выводит строку, на которую установлен указатель s в поток, на который установлен указатель stream. Символ ‘\0’, завершающий выводимую строку в поток не записывается. Если в процессе записи имела место ошибка, то рассматриваемая функция вернет EOF, в случае успеха возвращаемым значением функции fputs() является неотрицательное числа.

    Функция fgets() объявлена следующим образом:

    #include

    char* fputs(char* s, int n, FILE* stream);

    Функция fgets() читает не более n – 1 символов из потока на, который установлен указатель stream, в символьный массив, на который установлен указатель s. Существуют два способа завершения процесса чтения символов:

    • прочитан символ новая строка (‘\n’) ,

    • прочитан n – 1 символ.

    В первом случае прочитанный символ новая строка записывается в символьный массив, а затем строка завершается нуль – символом. Во втором случае символ новая строка оказывается непрочтенным и незаписанным в символьный массив. Однако и в этом случае в символьный массив будет записан нуль – символ.

    После успешного выполнения функция fgets() возвращает указатель на символьный массив, в который производилась запись. Если имело место достижение конца файла при условии, что ни один символ не был прочитан, возвращаемым значением функции fscanf() является NULL, а содержимое массива, на который установлен указатель s, оказывается неименным.

    1.11.4.10.Блоковый ввод – вывод


    Блоковый ввод – вывод обеспечивается функциями fread() и fwrite().

    Объявление функции fwrite() имеет следующий вид:

    #include

    size_t fwrite(const void* ptr, size_t n, size_t nmemb, FILE* stream);

    Функция fwrite() помещает до nmemb элементов (блоков), каждый из которых размером size, из массива адресуемого указателем ptr, в поток, на который установлен указатель stream.

    Функция fwrite() возвращает число успешно записанных элементов (блоков). Это значение может оказаться меньше, чем nmemb, если имеет место ошибка.

    #include

    size_t fread(void* ptr, size_t n, size_t nmemb, FILE* stream);

    Функция fwrite() читает до nmemb элементов (блоков), каждый из которых размером size, в массив адресуемого указателем ptr, из потока, на который установлен указатель stream.

    Функция fread() возвращает число успешно прочитанных элементов (блоков). Это значение может оказаться меньше, чем nmemb, если имеет место ошибка или обнаружен конец файла.

    1.11.5.Примеры решенных задач

    1.11.5.1.Пример 1. Табулирование функции с записью результатов на диск

    1.11.5.1.1.Постановка эадачи

    Табулировать функцию y = в n равноостоящих точках, начиная от значения x = xn вплоть до x = xk. Результаты табулирования записать в текстовый файл.
    1.11.5.1.2.Решение

    Один из возможных вариантов решения рассматриваемой задачи имеет следующий вид.

    /* Файл table.c. */

    #include

    #include

    #include
    void table_file(double xn, double xk, int n, FILE* out);

    int main(void)

    {

    int n;

    double x1, x2;

    FILE* out_file;

    clrscr();

    printf(“Количество расчетных точек = ”);

    scanf(“%d”, &n);

    printf(“Начальное значение аргумента=”);

    scanf(“%lf”, &x1);

    printf(“Конечное значение аргумента=”);

    scanf(“%lf”, &x2);
    if((out_file = fopen(“out_file.txt”, “w”) == NULL))

    {

    printf(“Не могу открыть файл out_file.txt\n”);

    exit(1);

    }
    table_file(x1, x2, n, out_file);

    fclose(out_file);

    printf(“Файл сформирован\n”);

    getch();

    return 0;

    }
    void table_file(double xn, double xk, int n, FILE* out)

    {

    double x, dx;

    int i ;

    fprintf(out, “%5s%15s%15s\n”, “Номер”, “Аргумент”, “Функция”);

    dx = (xk - xn) /(n - 1);

    x = xn;

    for(i = 1; i <= n; i++)

    {

    fprintf(out, “%5d%15.2f%15.2f\n”, i, x, x * x);

    x += dx;

    }

    }

    1.11.5.2.Пример 2. Запись содержимого двух массивов в текстовый файл

    1.11.5.2.1.Постановка задачи

    Имеются два массива, содержащие числа типа double. Записать содержимое этих массивов в текстовый файл. Вывод организовать в виде таблицы, снабженной заголовком. Таблица должна содержать три колонки. В первой колонке должен выводиться порядковый номер элемента, в двух других элементы массивов. В заголовке следует указать имена выводимых массивов.
    1.11.5.2.2.Решение

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

    #include

    void save_arrays(FILE* out, double* arr1, double* arr2,

    char* name1, char* name2, int num)

    {

    int i;

    fprinf(out, "%6s%15s%15s\n", "НОМЕР", name1, name2);

    for(i = 0; i < n; i++)

    {

    fprinf(out, "%6d%15.2f%15.2f\n", i, arr1[i], arr2[i]);

    }

    }


    1.11.5.3.Пример 3. Чтение из таблицы, хранящейся в файле, двух числовых массивов

    1.11.5.3.1.Постановка задачи

    В текстовом файле имеется таблица, в которой хранится содержимое двух массивов. Таблица содержит три колонки и снабжена заголовком, который находится в первой строке файла. В первой колонке представлен порядковый номер элемента, в двух других - элементы массивов.
    1.11.5.3.2.Решение

    Оформим решение данной задачи в виде функции. Эта функция должна иметь три параметра. Первый из них должен служить для передачи в функцию файлового указателя на файл, из которого будет выполняться чтение. Два других параметра необходимы для передачи массивов, в которые будет выполняться чтение данных. Количество прочитанных элементов массивов функция должна вернуть в качестве возвращаемого значения. Для чтения файла будет использоваться функция fgets из стандартной библиотеки языка C. Основу алгоритма функции должен составлять итерационный цикл чтения файла. До входа в цикл необходимо прочитать заголовок таблицы, а в его теле последовательно читать строки таблицы. Строка, полученная в результате чтения заголовка таблицы, в программе не используется.
    #include

    /* Чтение массивов */

    int load_arrays(FILE* in, double* arr1, double* arr2)

    {

    int count = 0;

    char buf[255];

    /* Чтение заголовка таблицы */

    fgets(buf, sizeof(buf), in);

    while(fgets(buf, sizeof(buf), in) != NULL)

    {

    sscanf(buf, "%*d%lf%lf", arr1 + count, arr2 + count);

    count++;

    }

    return count;

    }


    1.11.5.4.Пример 4. Вывод содержимого текстового файла на экран дисплея с проверкой на наличие ошибок.


    #include

    #include

    void display_file(FILE* in)

    {

    char buf[255];

    while(fgets(buf, sizeof(buf), in) != NULL)

    {

    fgets(buf, sizeof(buf), in);

    }

    if(ferror(in))

    {

    printf("Ошибка чтения файла\n");

    exit(1);

    }

    }


    1.11.5.5.Пример 5. Числовая матрица находится в текстовом файле. Первая строка файла содержит данные о размере матрицы. Вычислить сумму элементов в каждой строке матрицы.


    #include

    #include

    void summa_row_in_text_file(FILE* in, FILE* out)

    {

    int nrow;

    int ncol;

    int row;

    int col;

    double s, x;

    fscanf(in, "%d%d", &row, &col);

    for(row = 0; row < nrow; row++)

    {

    s = 0;

    for(col = 0; col < ncol; col++)

    {

    fscanf(in, "%lf", &x);

    s += x;

    }

    fprintf(out, "%10.3f\n", s);

    }

    }

    1.11.5.6.Пример 6. Сумма чисел в текстовом файле

    1.11.5.6.1.Постановка задачи

    В текстовом файле находятся вещественные числа. Количество строк в файле и количество чисел в строке произвольно. Вычислить сумму чисел, находящихся в файле. Решение задачи оформим в виде функции.
    1.11.5.6.2.Решение

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

    #include

    /* Вычисление суммы чисел в текстовом файле */

    double summa_in_text_file(FILE* in)

    {

    double s = 0;

    float x;

    while(fscanf(in, "%lf", &x) != EOF)

    {

    s += x;

    }

    return s;

    }


    Второй вариант реализации. Предусмотрена обработка ошибок чтения.

    #include

    #include

    /* Вычисление суммы чисел в текстовом файле */

    double summa_in_text_file(FILE* in)

    {

    double s = 0;

    double x;

    int result;

    while((result = fscanf(in, "%lf", &x)) != EOF)

    {

    if(result != 1)

    {

    printf("Ошибка при форматировании прочтенных данных\n");

    exit(1);

    }

    s += x;

    }

    if(ferror(in))

    {

    printf("Ошибка при чтении файла\n");

    exit(1);

    }

    return s;

    }

    1.11.5.7.Пример 7.



    /* Произвольный доступ, двоичный ввод - вывод */

    #include

    #include

    #include

    #define ARSIZE 1000

    double readNumber(FILE* in, int index);

    int main(void)

    {

    double numbers[ARSIZE];

    double value;

    const char* f1 = "numbers.dat";

    int i;

    long pos;

    FILE* in_out;
    /* Создаем массив чисел */

    for(i = 0; i < ARSIZE; i++)

    numbers[i] = i * i;

    if((in_out = fopen(f1, "wb")) == NULL)

    {

    fprintf(stderr, "Невозможно открыть %s для вывода.\n", f1);

    exit(1);

    }
    /* Записываем числа в файл */

    fwrite(numbers, sizeof *numbers, sizeof numbers, in_out);

    fclose(in_out);
    if((in_out = fopen(f1, "rb")) == NULL)

    {

    fprintf(stderr, "Невозможно открыть %s для произвольного\ ввода.\n", f1);

    exit(1);

    }
    /* Считываем выделенные объекты из файла */

    printf("Введите индекс в диапазоне 0 - %d.\n", ARSIZE - 1);

    scanf("%d", &i);

    printf("Значение равно %g.\n", readNumber(in_out, i));

    /* while(i >= 0 && i < ARSIZE)

    {

    pos = (long)i * sizeof * numbers;

    fseek(in_out, pos, SEEK_SET);

    fread(&value, sizeof *numbers, 1, in_out);

    printf("Значение равно %g.\n", value);

    printf("Следующий индекс (для выхода укажите индекс, не входящий в диапазон) : \n");

    scanf("%d", &i);

    }

    */

    fclose(in_out);

    puts("Пока");

    getch();

    return 0;

    }

    double readNumber(FILE* in, int index)

    {

    double value;

    long pos;

    pos = index * sizeof(double);

    fseek(in, pos, SEEK_SET);

    fread(&value, sizeof(double), 1, in);

    return value;

    }


    1.11.6. Контрольные вопросы и задачи для самостоятельной работы


    1. В чем состоит назначение файлов?

    2. В чем состоит отличие файлов от обычных переменных, объявляемых в программе?

    3. Какие виды библиотечных функций имеются в языке Си?

    4. В чем заключается различие между текстовыми и двоичными потоками?

    5. В чем состоит различие между потоком и файлом в языке Си?

    6. Каким образом объявляется файловый указатель?

    7. Из каких этапов складывается работа с файлами?

    8. Может ли текстовый файл использоваться в режиме прямого доступа?

    9. В чем состоит назначение процедуры Assign?

    10. Может ли текстовый поток быть открыт в режиме ввода – вывода?

    11. В каждой строке записано произвольное количество слов. Сформировать новый файл, дописав в конец каждой строки исходного файла ее номер.

    12. В конец каждой нечетной строки записать текст четной строки. Результаты вычислений записать в новый файл.

    13. Удалить из исходного файла все строки, длина которых не превосходит заданной величины.

    14. Поменять местами строки с четными и нечетными номерами. Результаты записать в новый файл.

    15. Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить произведение содержащихся в ней чисел, а затем выполнить сортировку файла в порядке убывания произведения. Результаты сортировки записать в новый файл.

    16. Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить сумму положительных чисел, а затем выполнить сортировку файла в порядке возрастания этой суммы. Результаты сортировки записать в новый файл.

    17. Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить сумму положительных чисел, а затем выполнить сортировку файла в порядке убывания этой суммы. Результаты сортировки записать в новый файл.

    18. Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить произведение положительных чисел, а затем выполнить сортировку файла в порядке убывания этого произведения. Результаты сортировки записать в новый файл.

    19. Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить значение медианы, которое затем записать в начало рассматриваемой строки. Результаты записать в новый файл.

    20. Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить значение медианы, которое затем записать в конец рассматриваемой строки. Результаты записать в новый файл.

    21. Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить значение медианы. Результаты записать в конец исходного файла.

    22. Имеется текстовый файл, содержащий действительные числа. Количество чисел в строке может быть любым. Количество строк не превосходит 100. Для каждой строки вычислить значение медианы. Результаты вычислений записать в новый файл.

    23. В файле хранится числовая матрица. В первой строке файла записаны два числа: количество строк и столбцов матрицы, а затем сама матрица. Количество столбцов матрицы не превосходит 10. Выполнить для каждой строки матрицы сортировку в порядке возрастания значений содержащихся в ней чисел. Результаты вычислений записать в новый файл.

    24. В файле хранится числовая матрица. В первой строке файла записаны два числа: количество строк и столбцов матрицы, а затем сама матрица. Количество столбцов матрицы не превосходит 10. Выполнить для каждой строки матрицы сортировку в порядке уменьшения значений содержащихся в ней чисел. Результаты вычислений записать в новый файл.







    написать администратору сайта