Курсач по программированию на языке высокого уровня

Задание было такое:

25.    Дан файл, содержащий сведения о владельцах автомобилей.
Структура записи файла: фамилия и инициалы владельца, марка и номер автомобиля.
Написать программу, которая  печатает
— фамилию владельца автомобиля с заданным номером;
— фамилии владельцев и номера автомобилей данной марки (в алфавитном порядке);
— количество автомобилей каждой марки.

А решение оказалось довольно длинным, зато красивым :-)

Вы можете скачать готовую работу в формате .docx, а также исполняемый файл программы со стандартным входным файлом в архиве .zip.
Ниже приводится исходный код программы:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <tchar.h>
//---------------------------------------------------------------------------
#define MAXMARK 50  //длина поля "марка"
#define MAXFIO 50   //длина поля "Фамилия И.О."
#define MAXNOM 7    //длина поля "Номер автомобиля"
#define COL 10      //количество выводимых за раз строк
#define ERROR_COLOR 12 //цвет сообщений об ошибках
//---------------------------------------------------------------------------
struct BD  //структура записи в виде списка
{
	char fio[MAXFIO]; //Фамилия инициалы
	char nom[MAXNOM]; //гос номер
	struct BD *sled; //следующая запись
};
struct marks
{
	char marka[MAXMARK];  //Марка
	int count;            //количество марок
	struct marks *sled;   //следующая запись
};
/**********************************************************/
/*rustext - функция перекодирования текста из ansi в ascii*/
/**********************************************************/
char* rustext(char *st)
{
	unsigned char *p = st;   //первый символ
	while (*p)   //пока строка не закончилась
	{
		if (*p&gt;=192)  //если код буквы &gt;192
			if (*p&lt;=239)  //если код буквы &lt;239
				*p-=64;   //вычитаем 64 из кода буквы для изменения кодировки
			else
				*p-=16;   //вычитаем 16 из кода буквы для изменения кодировки
		p++; //переход к следующему символу строки
	}
	return st; //возвращение начала строки
}
/************************************************************/
/*rustextin - функция перекодирования текста из ascii в ansi*/
/************************************************************/
char* rustextin(char *st)
{
	unsigned char *p = st;  //первый символ
	while (*p)   //пока строка не закончилась
	{
		if (*p&gt;=128)  //если код буквы &gt;128
			if (*p&lt;=175)  //если код буквы &lt;175
				*p+=64;   //прибавляем 64 к коду буквы для изменения кодировки
			else
				*p+=16;   //прибавляем 16 к коду буквы для изменения кодировки
		p++;  //переход к следующему символу строки
	}
	return st; //возвращение начала строки
}
/************************************************************/
/*vkl_marks – функция включения и подсчета марок автомобилей*/
/************************************************************/
void vkl_marks (struct marks **p, char marka[])//список всех марок
{   struct marks  *pt,  //новый элемент списка
				*k,     //текущий элемент
				*j;     //предыдущи элемент
	pt = (struct marks *) malloc(sizeof(struct marks));// создание нового элемента
	strcpy(pt-&gt;marka, marka);    //заполнение поля marka
	pt-&gt;count=1; //начальное значение счетчика
	if (*p==NULL || strcmp(pt-&gt;marka,(*p)-&gt;marka) &lt; 0) { //если элемент первый
		pt-&gt;sled=*p;  //добавление в начало
		*p=pt;
	}
	else { //вставка по алфавиту
		k=*p; //первый элемент списка
		//пока элемент не пустой и новый выше текущего по алфавитному
		while (k!=NULL &amp;&amp; strcmp(pt-&gt;marka,k-&gt;marka)&gt;=0)
		{
			j=k;      //предыдущий
			k=k-&gt;sled; //переход к следующему элементу
		}
		if (strcmp(pt-&gt;marka,j-&gt;marka)==0) { //если такая марка уже существует
			   j-&gt;count++;  //увеличиваем счетчик
		}
		else {
			j-&gt;sled=pt; //включение нового элемента после предыдущего
			pt-&gt;sled=k;
		}
	}
}
/************************************************************************/
/*vkl_fio – функция включения в таблицу владельцев и номеров автомобилей*/
/************************************************************************/
void vkl_fio (struct BD **p, char fio[], char nom[])
{   struct BD *pt,   //новый элемент списка
				*k,  //текущий элемент
				*j;  //предыдущий элемент
	pt = (struct BD *) malloc(sizeof(struct BD));   // создание нового элемента
	strcpy(pt-&gt;fio, fio);    //заполнение поля fio
	strcpy(pt-&gt;nom, nom);    //заполнение поля nom
	if (*p==NULL || strcmp(pt-&gt;fio,(*p)-&gt;fio) &lt; 0) { //если элемент первый
		pt-&gt;sled=*p;  //добавление в начало
		*p=pt;
	}
	else {          //вставка по алфавиту
		k=*p;//первый элемент списка
		//пока элемент не пустой и новый выше текущего по алфавитному списку
		while (k!=NULL &amp;&amp; strcmp(pt-&gt;fio,k-&gt;fio)&gt;=0)
		{
			j=k; //предыдущий
			k=k-&gt;sled; //переход к следующему элементу
		}
		j-&gt;sled=pt; //включение нового элемента после предыдущего
		pt-&gt;sled=k;
	}
}
/********************************************************************/
/*pars – функция разбиения строки на поля Фамилия И.О., марка, номер*/
/********************************************************************/
void pars(char string[], char fio[], char marka[], char nom[])
{
	int i=0, //указатель одного поля
		z=0; //указатель в массиве string[]
	if (strcmp(fio,"NONE")!=0) { //если нужно прочитать
		i=0; //обнуление указателя поля
		while (string[z]!=';') fio[i++]=string[z++];//чтение фамилии
		fio[i]='\0';  //добавление окончания строки
	}
	else  while (string[z]!=';') z++; //пропуск фамилии
	z++;  //пропуск ';'
	if (strcmp(marka,"NONE")!=0) { //если нужно прочитать
		i=0; //обнуление указателя поля
		while (string[z]!=';') marka[i++]=string[z++];//чтение марки
		marka[i]='\0';  //добавление окончания строки
	}
	else while (string[z]!=';') z++; //пропуск марки
	z++; //пропуск ';'
	if (strcmp(nom,"NONE")!=0) { //если нужно прочитать
		i=0; //обнуление указателя поля
		while ((string[z]!=';')&amp;&amp;(string[z]!='\n')) nom[i++]=string[z++];//чтение номера
		nom[i]='\0'; //добавление окончания строки
	}
}
/*********************************************/
/*Table_header – функция вывода шапки таблицы*/
/*********************************************/
void Table_header(int dl, char name1[], char name2[])
{
	int i,z;
	putch(201);
	for (i=0; i&lt;dl-1; i++, putch(205));  //горизонтальная линия
	putch(209);
	for (i=0; i&lt;13; i++, putch(205));
	putch(187);
	putch('\r'); //возвращение в начало строки
	putch('\n'); //перевод строки
	printf("%c%s",186,name1);
	for (z = 0;(name1[z]!='\0'); z++);//определение длины строки
	for (i=0; i&lt;dl-z-1; i++, putch(' ')); //заполнение пробелами
	printf("%c%s\t%c\n",179,name2,186);
}
/**********************************************************/
/*Table_line – функция вывода горизонтальной линии таблицы*/
/**********************************************************/
void Table_line(int dl)
{
	int i;
	putch(199);
	for (i=0; i&lt;dl-1; i++, putch(196));  //горизонтальная линия
	putch(197);
	for (i=0; i&lt;13; i++, putch(196));
	putch(182);
	putch('\r'); //возвращение в начало строки
	putch('\n'); //перевод строки
}
/************************************************************************/
/*Table_footer – функция вывода горизонтальной линии завершения таблицы */
/************************************************************************/
void Table_footer(int dl)
{
    int i;
	putch(200);
	for (i=0; i&lt;dl-1; i++, putch(205));  //горизонтальная линия
	putch(207);
	for (i=0; i&lt;13; i++, putch(205));
	putch(188);
	putch('\r'); //возвращение в начало строки
	putch('\n'); //перевод строки
}
/************************************************************/
/*fio_number – вывод владельца автомобиля с заданным номером*/
/************************************************************/
void fio_number(FILE *f)
{
	char nom[81],  //искомый номер
		nom2[MAXNOM], //номер в файле
		fio[MAXFIO],  //ФИО
		string[MAXMARK+MAXNOM+MAXFIO+3]; //стока в файле
	int i, //длина строки, циклическая переменная
		fl=0; //признак нахождения записи
	do
	{
		printf("Введите номер автомобиля: ");
		scanf("%s",&amp;nom);  //ввод искомого номера
		for (i = 0;(nom[i]!='\0')&amp;&amp;(i&lt;80); i++);//определение длины строки
		textcolor(ERROR_COLOR); //меняем цвет на цвет ошибок
		//если длина строки не соответствует длине номера, то вывод ошибки
		if (i!=MAXNOM-1) {
			cprintf("\rНомер введен не верно!!!\n\rПример номера: А123БВ\n\r");
			printf("Ввести номер еще раз? [y/n]: ");
			getchar(); //чтение  '\n'
			if (getchar()=='n') { //чтение и сравнение символа
				getchar(); //чтение '\n'
				return;   //выход из функции
			}
		}
	}
	while(i!=MAXNOM-1); //повторение запроса на ввод номера
	textcolor(7); //возвращение нормального цвета
	getchar(); //чтение '\n'
	printf("Вделец автомобиля с номером %s: ",nom);
	rustextin(nom);
	//пока файл не кончился и прочтенная строка не пустая
	while (!feof(f)&amp;&amp;(fl==0)&amp;&amp;fgets(string,MAXMARK+MAXNOM+MAXFIO+3,f))
	{
		pars(string,fio,"NONE",nom2);//обрабатываем прочитанную строку
		if (strcmp(nom,nom2)==0) { //сравнение номеров, если совпали...
			puts(rustext(fio)); //вывод фамилии
			fl=1; //признак нахождения владельца
		}
	}
	if (fl==0) {
		textcolor(ERROR_COLOR); //меняем цвет на цвет ошибок
		cprintf("не найден.\n\r");
	}
	rewind(f);  //возвращение в начало файла
}
/****************************************************************************/
/*fio_number_mark – вывод владельцев и номеров автомобилей с заданной маркой*/
/****************************************************************************/
void fio_number_mark(FILE *f)
{
	char fio[MAXFIO],  //поле Фамилия И.О.
		marka[MAXMARK], //поле Марка
		nom[MAXNOM],  //поле Номер
		marka2[MAXMARK], //искомая марка
		string[MAXMARK+MAXNOM+MAXFIO+3]; //строка в файле
	int i, //длина поля, циклическая переменная
		z; //количество выведенных строк
	struct BD *p,  //указатель на список с ФИО и номером
		*j;   //указатель на текущую запись
	p=NULL;   //инициализация списка
	printf("Введите название марки: ");
	gets(marka2);// чтение марки для поиска
	rustextin(marka2); //пребразование кодировки
	//пока файл не кончился и прочтенная строка не пустая
	while (!feof(f)&amp;&amp;fgets(string,MAXMARK+MAXNOM+MAXFIO+3,f))
	{
		pars(string,fio,marka,nom); //обрабатываем прочитанную строку
		if (strcmp(marka,marka2)==0) {//сравнение заданной марки с прочитанной
        	for (i = 0;(fio[i]!='\0'); i++);//определение длины строки
			while (i&lt;MAXFIO-1) fio[i++]=' ';//заполнение оставшегося места пробелами
			fio[i]='\0';  //добавление окончания строки
			vkl_fio(&amp;p,fio,nom);  //добавление совпадения в список
		}
	}
	if (p==NULL) {    //если ниченичего не нашлось
		textcolor(ERROR_COLOR);
		cprintf("Ничего не найдено.\n\r");
	}
	else { //если что-то нашлось
		textcolor(7);
		z=0; //колиство строк
		clrscr(); //очистка экрана
		Table_header(MAXFIO,"Фамилия И.О.","Номер");//шапка таблицы
		for(j=p;j!=NULL;j=j-&gt;sled)  //вывод найденного по алфавиту
		{
			Table_line(MAXFIO); //линия-разделитель
			printf("%c%s%c%s\t%c\n",186,rustext(j-&gt;fio),179,rustext(j-&gt;nom),186);
			z++;
			if ((z%COL)==0) {
				Table_footer(MAXFIO);//конец таблицы
				printf("Для продолжения нажмите любую клавишу...");
				getch();
				clrscr(); //очистка экрана
				Table_header(MAXFIO,"Фамилия И.О.","Номер");//шапка таблицы
			}
		}
		Table_footer(MAXFIO);//конец таблицы
	}
	while (p!=NULL) //удаление списка
	{
		j=p;
		p=j-&gt;sled;
		free(j);
	}
	rewind(f);  //возвращение в начало файла
}
/*********************************************/
/*mark_all – вывод всех марок и их количества*/
/*********************************************/
void mark_all(FILE *f)
{
	struct marks  *p,  //указатель на список с маркой и количеством
		*j;     //указатель на текущую запись
	int i,z;
	char mark[MAXMARK], //поле Марка
		string[MAXMARK+MAXNOM+MAXFIO+3]; //запись в файле
	clrscr(); //очистка экрана
	p=NULL;  //инициализация списка
	//пока файл не кончился и прочтенная строка не пустая
	while (!feof(f)&amp;&amp;fgets(string,MAXMARK+MAXNOM+MAXFIO+3,f))
	{
		pars(string,"NONE",mark,"NONE"); //выделение марки из строки
		for (i = 0;(mark[i]!='\0'); i++);//определение длины строки
		while (i&lt;MAXMARK-1) mark[i++]=' '; //заполнение пробелами
		mark[i]='\0';//окончание строки
		vkl_marks(&amp;p,mark); // включение марки в список
	}
	if (p==NULL) {    //если ничего не нашлось
		textcolor(ERROR_COLOR);
		cprintf("Файл пуст!.\n\r");
	}
	else   //если что-то нашлось
	{
		z=0; //количество строк
		textcolor(7);
		Table_header(MAXMARK,"Название марки","Количество");//шапка таблицы
		for(j=p;j!=NULL;j=j-&gt;sled)
		{
			Table_line(MAXMARK); //линия-разделитель
			printf("%c%s%c%d\t\t%c\n",186,rustext(j-&gt;marka),179,j-&gt;count,186);
			z++;
			if ((z%COL)==0) {
				Table_footer(MAXMARK);//конец таблицы
				printf("Для продолжения нажмите любую клавишу...");
				getch();
				clrscr(); //очистка экрана
				Table_header(MAXMARK,"Название марки","Количество");//шапка таблицы
			}
		}
		Table_footer(MAXMARK);//конец таблицы
	}
	while (p!=NULL)  //удаление списка из памяти
	{
		j=p;
		p=j-&gt;sled;
		free(j);
	}
	rewind(f); //возвращение в начало файла
}
/************************/
/*main – главная функция*/
/************************/
int main(int argc, _TCHAR* argv[])
{
	FILE *f; //файл с БД
	char ans; //буквенный ответ
	int ch_ans; //числовой ответ
	clrscr(); //очистка экрана
	if (argc==2) {//если указано имя файла
		if ((f=fopen(argv[1],"r"))==NULL) {// если файл открыть не удалось...
			textcolor(ERROR_COLOR);//установка цвета текста
			cprintf("File %s not found\r\nРабота программы не возможна!",argv[1]);
			return 1;
		}
	}
	else {// если имя файла НЕ указано
		textcolor(ERROR_COLOR); //установка цвета текста
		cprintf("Вы не указали файл с БД!\n\rБудет использован in.csv\n\r");
		printf("Завершить программу? [y/n]: ");
		ans=getchar(); //чтение символа
		if (ans=='y') {
			return 0;
		}
		argv[1]="in.csv";
		if ((f=fopen(argv[1],"r"))==NULL) {   //если файл отсутвует
			textcolor(ERROR_COLOR); //установка цвета текста
			cprintf("File %s not found\r\nРабота программы не возможна!",argv[1]);
			return 2;
		}
	}
	do
	{
		clrscr(); //очистка экрана
		textcolor(7); //установка цвета текста
		puts("1. Вывести фамилию владельца автомобиля с заданным номером");
		puts("2. Вывести фамилии владельцев и номера автомобилей данной, марки (в алфавитном порядке)");
		puts("3. Вывести количество автомобилей каждой марки");
		puts("4. Завершение программы");
		printf("Введите цифру нужного пункта: ");
		scanf("%d",&amp;ch_ans);  //читаем число
		getchar(); //чтение '\n'
		textcolor(ERROR_COLOR); //установка цвета текста
		switch (ch_ans) {
			//функция вывода владельца автомобиля с заданным номером
			case 1:	fio_number(f);
			break;
			//функция вывода владельцев и номеров данной марки
			case 2:	fio_number_mark(f);
			break;
			//функция вывода количества автомобилей каждой марки
			case 3:	mark_all(f);
			break;
			//выход
			case 4: return 0;
			default: cprintf("Введено неверное число!\n\r");
		}
		printf("Выйти из программы? [y/n]: ");
		ans=getchar(); //чтение символа
	}
	while (ans!='y');
	fclose(f);
	return 0;
}
Запись опубликована в рубрике Программирование, С с метками , , . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *