Язык программирования Cи
Пример 3
Написать программу создания карточки служащего с помощью структурного типа данных и указателя на структуру. Предусмотреть инициализацию полей структуры и изменение этих полей.
Для решения примера воспользуемся структурой, рассмотренной в теоретической части данной темы:
struct employee { |
|
char Name [20+1]; |
// имя |
char Surname [20+1]; |
// фамилия |
int age; |
// возраст |
double hourlysalary; |
// почасовой оклад |
} employee_new, *PTR; |
// *PTR – указатель на структуру |
Программный код решения примера
#include <stdio.h> #include <conio.h> #include <string.h> #include <locale.h>
// Предполагаемое число символов в имени или фамилии
#define n 20
int main (void) |
|
{ |
|
// Определение структуры |
|
struct emloyee |
|
{ |
|
char name[n+1]; |
// имя |
char surname[n+1]; |
// фамилия |
int age; |
// возраст |
double hourlysalary; |
// почасовой оклад в у.е. |
} emloyee_new, *PTR; |
// *PTR - указатель на структуру |
setlocale( LC_ALL, ".1251");// кодовая страница Windows – 1251 PTR = &emloyee_new; //В указатель помещается адрес employee_new
//Инициализация полей структуры strcpy_s(PTR -> name, n, "Владимир"); strcpy_s(PTR -> surname, n, "Викулов"); PTR -> age = 25;
PTR -> hourlysalary = 6.78;
//Вывод на консоль
puts("\n=============== Поля структуры ====================");
printf("\n Имя: %s\n Фамилия: %s\n возраст: %d лет\n
почасовой оклад: %1.2f y.e.\n", \PTR -> name, PTR -> surname, PTR -> age, PTR -> hourlysalary);
puts("\n==================================================\n"); printf("\n\n Нажмите любую клавишу (Press any key): "); _getch();
return 0;
}
В программе инициализация полей структуры выполнена с помощью оператора –>. С подключением заголовочного файла <locale.h> и определением прототипа функции setlocale(LC_ALL, ".1251") становится возможной поддержка русских шрифтов.
Результат выполнения программы представлен на рисунке.
7
Язык программирования Cи
Пример вывода полей структуры на консоль
Задание 3
1.В программу добавьте нумерацию полей структуры, например 1) имя: и т. д.
2.В программу введите свои имя и фамилию, возраст и размер получаемой стипендии (если нет, то нуль). Значения новых полей выведите на консоль и в текстовый файл с именем compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.
3.Инициализацию полей структуры выполните с помощью указателя.
4.Выполните предварительную инициализацию структуры, а затем смените значения полей.
Пример 4
Написать программу информационной карточки студенческой группы с данными о студентах, применив вложенные структуры.
Программный код решения примера
#include <stdio.h> #include <conio.h> #include <string.h>
// Размер символьных массивов
#define N 20 int main (void)
{
struct stud // шаблон структуры
{
char name[N+1]; |
// имя студента |
|
char surname[N+1]; |
// фамилия студента |
|
int age; |
// возраст - полных лет |
|
double av_mark; |
// средняя успеваемость |
|
}; |
|
|
struct group |
// шаблон структуры |
|
{ |
|
|
int number; |
// номер группы |
|
int quantity; |
// количество студентов в группе |
|
struct stud student; // вложенная структура |
||
} ACOUY; |
// ACOUY - структурная переменная |
//Инициализация полей структуры
ACOUY.number = 3; ACOUY.quantity = 21;
strcpy_s(ACOUY.student.name, N, "Peter"); strcpy_s(ACOUY.student.surname, N, "Bobrov"); ACOUY.student.age = 20; ACOUY.student.av_mark = 4.25;
//Вывод на консоль
puts("\n========= Varient field of structure ===============");
printf("\n Group Number: %d,\n The number of students in the group: %d,\n\ Name: %s,\n Surname: %s,\n Age: %d,\n Average mark: %1.2f", \ ACOUY.number, ACOUY.quantity, ACOUY.student.name, ACOUY.student.surname, \ ACOUY.student.age, ACOUY.student.av_mark);
8
Язык программирования Cи
puts("\n\n================================================\n"); printf("\n Press any key: ");
_getch(); return 0;
}
Результат выполнения программы показан на рисунке.
Пример информационной карточки студенческой группы
Задание 4
1.Инициализацию структуры выполните с клавиатуры.
2.Предусмотрите массив структур ACOUY[N], где N – количество групп (например, N = 3).
3.Введите данные своей студенческой группы и предусмотрите вывод на консоль данных о себе.
4.Примените оператор typedef и указатель на структуру.
Пример 5
Написать программу составления карточки на студента с динамическим распределением памяти для имени и фамилии на основе структурного типа данных [5].
Для динамического распределения памяти применим функцию malloc() и символьные указатели в качестве инициализаторов структуры.
Программный код решения примера
#include <stdio.h>
#include <conio.h> #include <string.h> #include <stdlib.h> #include <locale.h>
const int MAX = 80; // предполагаемое число символов
int main (void)
{
char *NAME, *SURNAME;
struct stud // шаблон структуры
{
char *name; // указатель вместо массива символов имени студента
char *surname; |
// указатель вместо |
массива символов фамилии |
int age; |
// возраст - полных лет |
|
float av_mark; |
// средняя успеваемость |
|
int letters; |
// число символов в имени и фамилии |
} TABLE, *PTR;
PTR = &TABLE; // инициализация указателя на структуру
NAME = (char *)malloc(MAX);
printf("\n Enter a name of the student: "); gets_s( NAME, MAX – 1 );
SURNAME = (char *)malloc(MAX);
printf(" Enter a surname of the student: "); gets_s( SURNAME, MAX – 1 );
// Распределение памяти для хранения "структурного" имени
9
Язык программирования Cи
PTR->name = (char *)malloc(strlen(NAME)+1);
//Копирование имени в распределенную память strcpy_s(PTR->name, strlen(NAME)+1, NAME);
//Распределение памяти для хранения "структурной" фамилии
PTR->surname = (char *)malloc(strlen(SURNAME)+1);
//Копирование фамилии в распределенную память
strcpy_s(PTR->surname, strlen(SURNAME)+1, SURNAME); printf(" Enter the age of the student: "); scanf_s("%d", &TABLE.age);
printf(" Enter an average mark of the student: "); scanf_s("%f", &TABLE.av_mark);
TABLE.letters = strlen(PTR->name) + strlen(PTR->surname);
//Для вывода чисел с десятичной запятой setlocale(LC_NUMERIC, ".1251");
puts("\n======== Varient field of structure ===============");
printf("\n Name: %s\n Surname: %s\n Age: %d\n Average mark: %1.2f\n\ The name and surname of student have: %d letters", \ PTR->name, PTR->surname, PTR->age, PTR->av_mark, PTR->letters);
puts("\n\n================================================\n");
//Освобождение памяти
free(NAME);
free(SURNAME); free(PTR->name); free(PTR->surname); printf("\n Press any key: "); _getch(); return 0;
}
В программе сначала выделяется память под имя и фамилию, для которых использованы указатели *NAME, *SURNAME. После того как эти данные введены с клавиатуры, рассчитывается количество символов плюс символ окончания строки '\0', которые используются при резервировании памяти для структурных переменных.
Возможный результат выполнения программы приведен на рисунке.
Пример динамического создания карточки студента
Задание 5
1.С клавиатуры введите данные о себе (буквами русского алфавита), выведите информацию на консоль и в текстовый файл с именем compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.
2.Поменяйте операторы «стрелка» на операторы «точка» и наоборот.
3.Вместо указателей *NAME, *SURNAME примените массивы символов.
4.Предусмотрите нумерацию полей структуры, например 1) Name: Peter и т. д.
Пример 6
Написать программу записи структуры в двоичный файл и чтения ее из этого файла.
10
Язык программирования Cи
Решение примера разобьем на две части: создадим структуру и произведем ее пакетную запись в файл. Потом операцию записи закомментируем, изменим поля структуры и выполним чтение структуры из файла.
Для динамического распределения памяти применим функцию malloc() и символьные указатели в качестве инициализаторов структуры.
Программный код решения примера
#include <stdio.h> #include <conio.h> #include <string.h>
#define MAX 80 // предполагаемое число символов struct stud // шаблон структуры
{
char name[MAX+1]; |
// массив символов имени студента |
char surname[MAX+1]; |
// массив символов фамилии студента |
char ACOUY[MAX+1]; |
// специальность |
int age; |
// возраст - полных лет |
float av_mark; |
// средняя успеваемость |
}; |
|
int main (void) |
|
{ |
|
char NAME[MAX+1], SURNAME[MAX+1], SPEC[MAX+1]; FILE *fid;
//условная инициализация переменной структуры и
//определение указателя на структуру
struct stud TABLE = {"--", "--", "--", 0, 0.0}, *PTR;
PTR = &TABLE; // инициализация указателя на структуру printf("\n Enter a name of student: ");
gets_s(NAME, MAX);
printf(" Enter a surname of student: "); gets_s(SURNAME, MAX);
printf(" Enter a speciality: "); gets_s(SPEC, MAX);
// Занесение имени в структуру strcpy_s(PTR->name, strlen(NAME)+1, NAME); // Занесение фамилии в структуру
strcpy_s(PTR->surname, strlen(SURNAME)+1, SURNAME);
// Занесение названия специальности в структуру strcpy_s(PTR->ACOUY, strlen(SPEC)+1, SPEC); printf("Enter the age of the student: "); scanf_s("%d", &TABLE.age);
printf(" Enter the average mark student: "); scanf_s("%f", &TABLE.av_mark);
puts("\n======= Varient field of structure ============");
printf("\n Name: %s\n Surname: %s\n \
Specialisation: %s\n Age: %d\n Average mark: %0.2f\n ", \ PTR->name, PTR->surname, PTR->ACOUY, PTR->age, PTR->av_mark );
puts("\n================================================\n"); if ( fopen_s(&fid, "D:\\data12.dat", "wb") )
{
printf("\n File could not be opened\n"); printf("\n Press any key: ");
_getch(); return -1;
}
//Пакетная запись в двоичный файл fwrite(PTR, sizeof(struct stud), 1, fid); fclose(fid);
//if ( fopen_s(&fid, "D:\\data12.dat", "rb") ) //{printf("\n File could not be opened\n"); //printf("\n Press any key: ");
11
Язык программирования Cи
//_getch(); return -1; }
// Чтение из двоичного файла
//fread(PTR, sizeof(struct stud), 1, fid); //puts("\n===== Variants of fields of structure =====");
//printf("\n Name: %s\n Surname: %s\n \
//Specialisation: %s\n Age: %d\n Average mark: %1.2f\n ", \
//PTR->name, PTR->surname, PTR->ACOUY, PTR->age, PTR->av_mark ); //puts("\n===============================================\n"); //fclose(fid);
printf("\n\n Press any key: "); _getch();
return 0;
}
Форматы записи в двоичный файл и чтения из него выглядят так: fwrite(PTR, sizeof(struct stud), 1, fid); fread(PTR, sizeof(struct stud), 1, fid);
Вфункции fwrite() первый параметр PTR определяет содержимое структуры (данных в других случаях), которое по указателю на файл *fid записывается в файл. Второй параметр sizeof(struct stud) определяет размер структуры в байтах. Третий параметр 1
–это количество блоков, которое будет записываться в файл. Второй и третий параметры перемножаются, поэтому их можно поменять местами.
Впрограмме чтение из двоичного файла закомментировано. Для корректной работы программы сделана условная инициализация полей структуры, чтобы прописать адрес структуры в памяти с данными.
Возможный вариант выполнения программы при записи информации в двоичный файл представлен на рисунке.
Вариант записи информации в двоичный файл Результат выполнения программы после комментирования программного кода с за-
писью в файл и снятия комментариев к программному коду чтения из файла показан на рисунке.
Результат чтения из двоичного файла
12