Программы на языке С, состоящие из нескольких файлов
Задание 1
- Проверьте работу программ при записи результата в файл. В качестве имени текстового файла примите compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.
- В файле hfile.h поменяйте местами подключаемые файлы. Добавьте необходимые изменения, чтобы программа работала корректно (без предупреждений).
- Вместо разработанной функции degree() примените стандартную функцию pow().
- В программу добавьте изменения для вывода матрицы планирования при зеркальном отображении столбцов.
- В матрицу планирования добавьте в качестве первого столбца массив положительных единиц, т.е. +1.
Пример 2. Напишите программу вывода на консоль содержимого текстового файла, расположенного в заданном каталоге. Вывод на консоль содержимого файла оформить в виде отдельного файла.
Предположим, что программный проект расположен на диске Е:\Project_C. Текстовый файл расположен на диске D:\data16.txt. Пусть содержимое текстового файла будет следующим:
1, 2, 3, 4, 5 Programming in C department: electronic engineering
Программный код решения примера:
// Подключаемый файл fun1.c #include <stdlib.h> // Для функции exit() void print_file(char *st) { char str[79+1]; FILE *fid; printf("\n Data from \"%s\":\n", st); if ( (fopen_s(&fid, st, "r")) ) { printf("\n File could not be opened.\n"); printf("\n Break. Press any key: "); _getch(); exit(1); } printf("\n Data from the file \"%s"\n", st); while (!feof(fid)) { fgets(str, 79, fid); printf("%s", str); } fclose(fid); printf("\n"); }
// Основной программный модуль проекта main.c #include <stdio.h> #include <conio.h> #include "D:\\fun1.c" // Главная функция int main (void) { char str[79+1]; printf("\n Enter the file name and path: "); gets_s(str, 79); // Вызов функции распечатки файла print_file(str); printf("\n Press any key: "); _getch(); return 0; }
Результат выполнения программы показан на рис. 17.5.
Задание 2
- На консоль выведите содержимое подключаемого файла fun1.c.
- Измените расположение подключаемого файла, например, поместите его на диск D:\students\fun1.c.
- В текстовый файл запишите фамилию и имя пользователя (студента), год рождения, год поступления в университет, наименование специальности.
- Содержимое текстового файла предыдущего пункта выведите на консоль и запишите в другой текстовый файл с именем compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа. Запись в текстовый файл оформите в виде функции surname.c, где surname – фамилия пользователя.
- В программе вместо указателя, являющегося формальным параметром функции print_file(), примените массив символов.
Пример 3. Напишите программу преобразования десятичной системы счисления в двоичную, восьмеричную, шестнадцатеричную на основе системы меню. Примените массив указателей на функцию, используйте заголовочные файлы.
Перевод заданного десятичного числа в соответствующее число по заданному основанию оформим в виде трех функций, каждая из которых будет вызываться по индексу, по которому из массива будет выбираться указатель на нужную функцию. Прототипы функций включим в заголовочный h -файл. Основания систем счисления также поместим в заголовочный h -файл. Для решения примера используем программы предыдущего примера.
Программный код решения примера состоит из шести файлов:
// Основной программный модуль main.c #include <stdio.h> #include <conio.h> #include "hdec.h" int main (void) { int index[3] = {0, 1, 2}; long int number; int basen; void (*fun[3])(long int) = {dec2, dec8, dec16}; printf("\n Enter a positive integer numbers: "); scanf_s("%ld", &amp;amp;amp;number); printf("\n Select base system notation (2, 8, 16): "); scanf_s("%d", &basen); if (basen == 2) (*fun[0])(number); else if (basen == 8) (*fun[1])(number); else if (basen == 16) (*fun[2])(number); else { printf("\n\t Error choice."); printf("\n Break. Press any key: "); _getch(); return 0; } printf("\n\n Press any key: "); _getch(); return 0; }
// Подключаемый файл Dec_2.c // Перевод в двоичную систему счисления #include "base.h" void dec2 (long int x) { int i = 0; int Num[64]; int next; long int xx = x; do { Num[i] = x % base2; ++i; x /= base2; } while (x != 0); // Результат в обратном порядке printf("\n Decimal number \"%ld\" has a binary equivalent:\n", xx); for (--i; i >= 0; --i) { next = Num[i]; printf("%2d", next); } }
// Подключаемый файл Dec_8.c // Перевод в восьмеричную систему счисления #include "base.h" void dec8 (long int y) { int i = 0, next; int Num[64]; long int yy = y; do { Num[i] = y % base8; ++i; y /= base8; } while (y != 0); // Результат в обратном порядке printf("\n Decimal number \"%ld\" has an octal equivalent:\n", yy); for (--i; i >= 0; --i) { next = Num[i]; printf("%2d", next); } }
// Подключаемый файл Dec_16.c // Перевод в шестнадцатеричную систему счисления #include "base.h" void dec16 (long int z) { int i = 0; int Num[64]; int next; long int zz = z; const char digits_16[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; do { Num[i] = z % base16; ++i; z /= base16; } while (z != 0); // Результат в обратном порядке printf("\n Decimal number \"%ld\" has a hexadecimal equivalent:\n", zz); for (--i; i >= 0; --i) { next = Num[i]; printf("%2c", digits_16[next]); } }
// Подключаемый файл base.h // Основания систем счисления #define base2 2 #define base8 8 #define base16 16
// Подключаемый файл hdec.h // Поключение файлов с функциями преобразования систем // счисления #include "Dec_2.c" #include "Dec_8.c" #include "Dec_16.c" // Прототипы функций преобразования систем счисления void dec2 (long int a); void dec8 (long int b); void dec16 (long int c);
В программе используется заголовочный файл base.h в целях демонстрации препроцессорных директив языка С. Другой заголовочный файл hdec.h подключает файлы с программами преобразования чисел и прототипы функций. Внимание! Особенность создания h -файлов заключается в том, что они должны заканчиваться пустой строкой (после всех операторов, прототипов функций и пр.)
Файлы Dec_2.c, Dec_8.c, Dec_16.c, base.h, hdec.h созданы с помощью инструментальной среды Microsoft Visual Studio 2010 при создании нового файла из меню File–New–File с последующим выбором: либо h -файлы, либо cpp -файлы с последующим установлением расширения языка С, т.е. . с. Созданные файлы следует сохранить в папке с основным программным котодом типа main.c.
В программе использован массив указателей на функцию. По определению указатель на функцию содержит адрес первого байта или слова выполняемого кода функции. Над указателями на функцию запрещены арифметические операции. Так же как и для других типов переменных, можно использовать массив указателей на функцию. Соответствующая функция вызывается с указанием индекса требуемой функции. Например:
(*fun[0])(number);
Десятичное число number передается в функцию dec2(). Нулевой индекс соответствует выбору функции перевода десятичного числа в двоичный эквивалент.
Расположение файлов с созданными функциями в основной папке проекта, где находится файл main.c, позволяет подключать необходимые файлы как в текущей папке (директории).
Возможный результат выполнения программы показан на рис. 17.6.