IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным. В описании темы указываем язык!!!

 
 Ответить  Открыть новую тему 
> Структуры со списками в Си
Nike0
сообщение 7.01.2011 13:16
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 61
Пол: Мужской
Реальное имя: Илья

Репутация: -  0  +


Доброго времени суток, задача состоит в том, чтобы создать структуру, текстовый ввод-вывод(консольный и файловый), также накоряжил очень много кода, есть проблемки, кое-что работает, кое-что нет, поэтому прошу помочь найти ошибки и исправить их, если есть возможность и желание. Комментарии присутствуют, поэтому думаю будет проще разобраться, чем читать сырой код:
/* Для сокращения записи типа структуры введем следующую константу */
#define emlp struct _emlp
#include  <stdio.h>
#include <alloc.h>
/* Описание структуры */
emlp
{
   char name[30]; /* Вид траспорта */
   int  num; /* Номер маршрута */
   char nachalo[30]; /* Начальная остановка */
   char konec[30]; /* Конечная остановка */
   char time[20]; /* Время пути */
   emlp *next; /* Указатель на следующий элемент */
};

emlp *emlph=NULL; /* Начало списка */
char fname[]="D_STRUCT.txt"; /* Файл для хранения списка */

/* Функция печати списка */
int f_print()
{
		emlp *a; /* Указатель на структуру */
		int i, j;
		/* Если списка нет в памяти,то вывод соотвтствуюшего
		   сообщения */
		/* Иначе - вывод всего списка на экран */
		if (emlph==NULL)
			printf("List empty\n");
		else
		{
			for (a=emlph,i=1,j=1; a!=NULL; a=a->next,j++,i++)
			{
				printf("#%-2d %-30s  %-4d  %-30s %-30s %-20s\n",
					i,a->name,a->num,a->nachalo,a->konec,a->time);
				if (j==10)
				{
					printf("Press any key for continue...\n");
					getch();
					j=1;
				}
			}
			printf("======= end of list ========\n");
		}
		return 0;
}

/* Функция ввода списка */
int f_input()
{
		int cc;
		printf("Enter name=* for end of stream\n");
		/* Конец ввода - при вводе '*' вместо имени */
		while (!(cc=f_add())); /* Вызов функции добавления */
		return cc;
}

/* Добавление элемента в список */
int f_add()
{
		emlp *a, *b;
		char ss[60];
		int i=1;
		/* Если список существует,осуществляем вставку элемента */
		if (emlph!=NULL)
			for (i++,a=emlph; a->next!=NULL; a=a->next,i++);
			/* Приглашение к вводу */
				printf("Line #%d. Enter: 'Vid transporta' 'Nomer marshruta' 'Nachalnaya ostanovka' 'Konechanaya ostanovka' 'Vremya v puti' >",i);
				scanf("%s",ss);
				if (ss[0]=='*')
					return 2;
			/* Выделение памяти под новый элемент */
			b = (emlp *)malloc(sizeof(emlp));
			strcpy(b->name,ss);
			scanf("%d",&(b->num));
			strcpy(b->nachalo,ss);
			strcpy(b->konec,ss);
			strcpy(b->time,ss);
			b->next=NULL;
			/* Элемент вставляется после головы списка или в начало,
			если список пустой */
			if (emlph==NULL)
				emlph=b;
			else
				a->next=b;
		return 0;
}

/* Уничтожение элемента списка */
int f_delete ()
{
		int ln;
		emlp *a, *b;
		/* Если списка нет в памяти,то вывод соотвтствуюшего
		сообщения */
		if (emlph==NULL)
			printf("List empty\n");
		/* Иначе-ввод номера элемента с помощью функции GET_LN */
		else
		{
			ln=get_ln()-1;
			if (!ln)
			{
				/*  Если номер корректен - переприсваивание указателей
				и освобождение памяти */
				a=emlph;
				emlph=a->next;
				free(a);
			}
			else
			{
				/* Иначе- ??????? */
				for(ln--, a=emlph; ln&&(a!=NULL); a=a->next,ln--);
					if (a!=NULL)
						if ((b=a->next)!=NULL)
						{
							a->next=b->next;
							free(b);
						}
			}
		}
		return 0;
}

/* Изменение значения полей элемента списка */
int f_change()
{
		char ss[60];
		int ln;
		emlp *a;
		ln=get_ln()-1; /* Ввод номера элемента */
		for (a=emlph; ln && a!=NULL; ln--, a=a->next);
			if (ln)
				return 0;
		/* Вывод старых и ввод новых значений */
		/* Запись новых значений в список */
			printf("Old name  = %s   New name >",a->name);
			gets(ss);
		if (*ss)
			strcpy(a->name,ss);
			printf("Old num = %d   New num >",a->num);
			gets(ss);
		if (*ss)
			sscanf(ss,"%d",&(a->num));
			printf("Old nachalo = %s   New nachalo >",a->nachalo);
			gets(ss);
		if (*ss)
			strcpy(a->nachalo,ss);
			printf("Old konec = %s   New konec >",a->konec);
			gets(ss);
		if (*ss)
			strcpy(a->konec,ss);
			printf("Old time = %s   New time >",a->time);
			gets(ss);
		if (*ss)
			strcpy(a->time,ss);
			return 0;
}

/* Функция сортировки списка */
int f_sort()
{
		int n;
		emlp *a, *b, *c;
		/* Если список пустой или в нем один элемент,
		то выход из функции */
		if ((emlph==NULL)||(emlph->next==NULL))
			return 0;
		/* Сортировка списка методом "пузырька" */
		for (n=1; n; )
		{
			n=0;
			for (a=emlph, b=emlph->next; b!=NULL;)
				if (strcmp(a->name,b->name)>0)
				{
					a->next=b->next;
					b->next=a;
					if (a==emlph)
						emlph=b;
					else
						c->next=b;
						c=b;
						b=a->next;
						n=1;
				}
				else
				{
					c=a;
					a=b;
					b=b->next;
				}
	   }
	   return 0;
}

/* Функция сохранения списка на диске */
int f_save()
{
		FILE *dat;
		emlp *a;
		dat=fopen(fname,"w"); /* Открытие файла на запись */
		/* Запись в файл осуществляется  полями */
		for (a=emlph; a!=NULL; a=a->next)
		fprintf(dat,"%s %d %s %s %s\n",a->name,a->num,a->nachalo,a->konec,a->time);
		/* В конце файла - спецкод '***' */
		fprintf(dat,"***\n");
		fclose(dat);        /* Закрытие файла */
		return 0;
}

/* Перезапись списка из файла в динамическую память */
int f_restore()
{
		FILE *dat;
		char ss[60];
		emlp *a, *b;
		/* Открытие файла для чтения,если файл не найден-вывод
			соответствующего сообщения */
		if ((dat=fopen(fname,"r"))==NULL)
		{
			printf("File not found : %s\n",fname);
			return 1;
		}
		else
		{
			emlph=NULL;
			do
			{
				/* Чтение из файла по полям пока не дошли до
				спецкода '* '*/
				fscanf(dat,"%s",ss);
				if (ss[0]!='*')
				{
					/* Выделение памяти под новый элемент */
					b = (emlp *)malloc(sizeof(emlp));
					if (emlph==NULL)
						emlph=b;
					else
						a->next=b;
						strcpy(b->name,ss);
						scanf("%d",&(b->num));
						strcpy(b->nachalo,ss);
						strcpy(b->konec,ss);
						strcpy(b->time,ss);
						b->next=NULL;
						a=b;
				}
			} while (ss[0]!='*');
			fclose(dat);  /* Закрытие файла */
	   }
	   return 0;
}
/* Ввод номера элемента */
int get_ln ()
{
		int ln;
		printf("Enter line number >");
		do
		{
			/* Ввод номера элемента и проверка его(если он меньше единицы-
			выдается сообщение об ошибке */
			scanf("%d",&ln);
			if (ln<1)
			{
				printf("Illegial line number. Try again >");
				ln=0;
			}
		} while (!ln);
		return ln;
}

main()
{
	char eoj; /* Флаг окончания работы */
	int i; /* Вспомогательная переменная */
	/* Структура меню */
	struct
	{
		int op; /* Номер операции */
		(*opf)(); /* Функция обработки */
	}
		m[9] =
		{
		{'1',f_print},{'2',f_input},{'3',f_add},
		{'4',f_delete},{'5',f_change},{'6',f_sort},
		{'7',f_save},{'8',f_restore},{'0',}
	};
	int  opcode; /* Код операции */
	for ( ; ; )  /* Пока не конец работы */
	{
		clrscr();           /* Очистка экрана */
		printf("1. Print\n");  /* Вывод пунктов меню на экран */
		printf("2. Input\n");
		printf("3. Add\n");
		printf("4. Delete\n");
		printf("5. Change\n");
		printf("6. Sort\n");
		printf("7. Save\n");
		printf("8. Restore\n");
		printf("0. Quit\n");
		printf("Enter operation code > "); /* Запрос на ввод номера
										  пункта для выполнения */
		opcode=getche(); /* Ввод номера пункта */
		putchar('\n');
		if (opcode=='0') /* выход из программы, если выбран QUIT */
		{
		  printf("Press any key...");
		  getch();
		  exit(0);
		}
		for (i=0; i<9;i++)
		{  /* Запуск соответствующей функции обработки */
			if (opcode==m[i].op)
			{
				if (m[i].opf()==1)
					exit(0);
					break;
			}
		}
	}
	getch();
}
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.01.2011 13:29
Сообщение #2


Гость






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

P.S. Сразу: в третьей строке, после описания заголовка for, точка с запятой зачем? чтоб был пустой цикл? тебе это удалось, дальше что происходит? Если так и задумано - почему отформатировано так, будто ты ожидаешь что ввод данных производится внутри цикла?

		/* Если список существует,осуществляем вставку элемента */
		if (emlph!=NULL)
			for (i++,a=emlph; a->next!=NULL; a=a->next,i++); 
			/* Приглашение к вводу */
				printf("Line #%d. Enter: 'Vid transporta' 'Nomer marshruta' 'Nachalnaya ostanovka' 'Konechanaya ostanovka' 'Vremya v puti' >",i);
				scanf("%s",ss);
				if (ss[0]=='*')
					return 2;


В общем, я уже сказал: показывай, где именно не работает, и как это воспроизвести...
 К началу страницы 
+ Ответить 
Nike0
сообщение 7.01.2011 15:58
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 61
Пол: Мужской
Реальное имя: Илья

Репутация: -  0  +


все, нашел ошибки, а суть заключалась в том, что я ввожу данные, сохраняю их в файле, затем, выхожу-захожу, должно прочитать файл и вывести данные на экран, ну а также стандартные операции в структурах, вот готовый код, может кому понадобиться:
/********************* Файл LAB3.C ****************************/
/* Для сокращения записи типа структуры введем следующую константу */
#define emlp struct _emlp
/* Функция печати списка */
int f_print();
/* Функция ввода списка */
int f_input();
/* Добавление элемента в список */
int f_add();
/* Уничтожение элемента списка */
int f_delete();
/* Изменение значения полей элемента списка */
int f_change() ;
/* Функция сортировки списка */
int f_sort();
/* Функция сохранения списка на диске */
int f_save();
/* Перезапись списка из файла в динамическую память */
int f_restore();

#include <stdio.h>
#include <alloc.h>
/* Описание структуры */
emlp
{
	char trans[20]; /* Транспорт */
	int num; /* Номер */
	char marsh[40]; /* Маршрут */
	int time; /* Время */
	emlp *next; /* Указатель на следующий элемент */
};

emlp *emlph=NULL; /* Начало списка */
char fname[]="D_STRUCT.DA1"; /* Файл для хранения списка */

main()
{
	char eoj; /* Флаг окончания работы */
	int i; /* Вспомогательная переменная */
	/* Структура меню */
	struct
	{
		int op; /* Номер операции */
		(*opf)(); /* Функция обработки */
		} m[9] = {{'1',f_print},{'2',f_input},{'3',f_add},
				  {'4',f_delete},{'5',f_change},{'6',f_sort},
				  {'7',f_save},{'8',f_restore},{'0',}
	};
	int opcode; /* Код операции */
	for ( ; ; )
	{ /* Пока не конец работы */
		clrscr(); /* Очистка экрана */
		printf("1. Print\n"); /* Вывод пунктов меню на экран */
		printf("2. Input\n");
		printf("3. Add\n");
		printf("4. Delete\n");
		printf("5. Change\n");
		printf("6. Sort\n");
		printf("7. Save\n");
		printf("8. Restore\n");
		printf("0. Quit\n");
		printf("Enter operation code > "); /* Запрос на ввод номера
											пункта для выполнения */
		opcode=getche(); /* Ввод номера пункта */
		putchar('\n');
		if (opcode=='0')
		{ /* выход из программы, если выбран QUIT */
			printf("Press any key...");
			getch();
			exit(0);
		}
		for (i=0; i<10;i++)
		{ /* Запуск соответствующей функции обработки */
			if (opcode==m[i].op)
			{
				if (m[i].opf()==1)
					exit(0);
					break;
			}
		}
	}
}
/****************************************************************/
/**************** Функция вывода списка на экран ****************/
/****************************************************************/
f_print()
{
	emlp *a; /* Указатель на структуру */
	int i, j;
	/* Если списка нет в памяти,то вывод соотвтствуюшего сообщения */
	/* Иначе - вывод всего списка на экран */
	if (emlph==NULL)
		printf("List empty\n");
	else
	{
		for (a=emlph,i=1,j=1; a!=NULL; a=a->next,j++,i++)
		{
			printf("#%-2d %-10s %-4d %-20s %-4d\n",i,a->trans, a->num, a->marsh,a->time);
			if (j==20)
			{
				printf("Press any key for continue...\n");
				getch();
				j=1;
			}
		}
		printf("======= end of list ========\n");
	}
	getch();
	return 0;
}
/****************************************************************/
/*********** Функция ввода элементов списка **********************/
/****************************************************************/
f_input()
{
	int cc;
	printf("Enter nazvanie=* for end of stream\n");
	/* Конец ввода - при вводе '*' вместо имени */
	while (!(cc=f_add())); /* Вызов функции добавления */
	return cc;
}
/****************************************************************/
/************* Добавление элемента в список *********************/
/****************************************************************/
int f_add()
{
	emlp *a, *b;
	char ss[40];
	int i=1;
	/* Если список существует,осуществляем вставку элемента */
	if (emlph!=NULL)
		for (i++,a=emlph; a->next!=NULL; a=a->next,i++);
		/* Приглашение к вводу */
			printf("Line #%d. Enter: transport nomer marshrut time >",i);
			scanf("%s",ss);
			if (ss[0]=='*')
				return 2;
				/* Выделение памяти под новый элемент */
	b=(emlp *)malloc(sizeof(emlp));
	strcpy(b->trans,ss);
	scanf("%d %s %d",&(b->num),&(b->marsh),&(b->time));
	b->next=NULL;
	/* Элемент вставляется после головы списка или в начало,
	если список пустой */
	if (emlph==NULL)
		emlph=b;
	else
		a->next=b;
	return 0;
}
/*****************************************************************/
/************ Функция сохранения списка на диске *****************/
/*****************************************************************/
f_save()
{
	FILE *dat;
	emlp *a;
	dat=fopen(fname,"w"); /* Открытие файла на запись */
	/* Запись в файл осуществляется полями */
	for (a=emlph; a!=NULL; a=a->next)
		fprintf(dat,"%s %d %s %d\n",a->trans,a->num,a->marsh,a->time);
		/* В конце файла - спецкод '***' */
	fprintf(dat,"***\n");
	fclose(dat); /* Закрытие файла */
return 0;
}
/****************************************************************/
/****** Перезапись списка из файла в динамическую память ********/
/****************************************************************/
f_restore()
{
	FILE *dat;
	char ss[40];
	emlp *a, *b;
	/* Открытие файла для чтения, если файл не найден-вывод
	соответствующего сообщения */
	if ((dat=fopen(fname,"r"))==NULL)
	{
		printf("File not found : %s\n",fname);
		return 1;
	}
	else
	{
		emlph=NULL;
		do
		{
		/* Чтение из файла по полям пока не дошли до
		спецкода '* '*/
			fscanf(dat,"%s",ss);
			if (ss[0]!='*')
			{
			/* Выделение памяти под новый элемент */
				b=(emlp *)malloc(sizeof(emlp));
				if (emlph==NULL)
					emlph=b;
				else
					a->next=b;
				strcpy(b->trans,ss);
				fscanf(dat,"%d %s %d\n",&(b->num),&(b->marsh),&(b->time));
				b->next=NULL;
				a=b;
			}
		} while (ss[0]!='*');
	fclose(dat); /* Закрытие файла */
	}
	return 0;
}
/*****************************************************************/
/*************** Функция сортировки списка ***********************/
/*****************************************************************/
f_sort()
{
	int n;
	emlp *a, *b, *c;
	/* Если список пустой или в нем один элемент,
	то выход из функции */
	if ((emlph==NULL)||(emlph->next==NULL))
		return 0;
	/* Сортировка списка методом "пузырька" */
	for (n=1; n; )
	{
		n=0;
		for (a=emlph, b=emlph->next; b!=NULL; )
			if (strcmp(a->trans,b->trans)>0)
			{
				a->next=b->next;
				b->next=a;
				if (a==emlph)
					emlph=b;
				else
					c->next=b;
				c=b;
				b=a->next;
				n=1;
			}
			else
			{
				c=a;
				a=b;
				b=b->next;
			}
	}
	return 0;
}
/*****************************************************************/
/************ Ввод номера элемента *******************************/
/*****************************************************************/
int get_ln ()
{
	int ln;
	printf("Enter line number >");
	do
	{
	/* Ввод номера элемента и проверка его(если он меньше единицы-
	выдается сообщение об ошибке */
		scanf("%d",&ln);
		if (ln<1)
		{
			printf("Illegial line number. Try again >");
			ln=0;
		}
	} while (!ln);
	return ln;
}
/*****************************************************************/
/************* Уничтожение элемента списка ***********************/
/*****************************************************************/
f_delete ()
{
	int ln;
	emlp *a, *b;
	/* Если списка нет в памяти, то вывод соотвтствуюшего
	сообщения */
	if (emlph==NULL)
		printf("List empty\n");
	/* Иначе-ввод номера элемента с помощью функции GET_LN */
	else
	{
		ln=get_ln()-1;
		if (!ln)
		{
			/* Если номер корректен - переприсваивание указателей
			и освобождение памяти */
			a=emlph;
			emlph=a->next;
			free(a);
		}
		else
		{
		/* Иначе- ??????? */
			for(ln--, a=emlph; ln&&(a!=NULL); a=a->next,ln--);
				if (a!=NULL)
					if ((b=a->next)!=NULL)
					{
						a->next=b->next;
						free(b);
					}
		}
	}
	return 0;
}
/*****************************************************************/
/********** Изменение значения полей элемента списка *************/
/*****************************************************************/
f_change()
{
	char ss[40];
	int ln;
	emlp *a;
	ln=get_ln()-1; /* Ввод номера элемента */
	for (a=emlph; ln && a!=NULL; ln--, a=a->next);
		if (ln)
			return 0;
	/* Вывод старых и ввод новых значений */
	/* Запись новых значений в список */
	printf("Old transport = %s New transport >",a->trans);
	gets(ss);
	gets(ss);
	if (*ss)
		strcpy(a->trans,ss);
	printf("Old nomer = %d New nomer >",a->num);
	gets(ss);
	if (*ss)
		sscanf(ss,"%d",&(a->num));
	printf("Old marshrut = %s New marshrut >",a->marsh);
	gets(ss);
	gets(ss);
	if (*ss)
		strcpy(a->marsh,ss);
	printf("Old time = %d New time >",a->time);
	gets(ss);
	if (*ss)
		sscanf(ss,"%d",&(a->time));
	return 0;
}
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 7.01.2011 16:08
Сообщение #4


Гость






Цитата
вот готовый код, может кому понадобиться:
Хм. Кому может понадобиться код, который не компилируется GCC? Это что, какой-то компилятор разрешает так делать (я про описание opf) :
Цитата
	struct
	{
		int op; /* Номер операции */
		(*opf)(); /* Функция обработки */
		} m[9] = /* тут была инициализация, причем тоже не особо удачная */
? Тогда указывай в начале в комментариях, что код должен компилироваться только этим компилером, все те, у кого его нет - не теряйте времени!
 К началу страницы 
+ Ответить 
Nike0
сообщение 7.01.2011 16:29
Сообщение #5


Пионер
**

Группа: Пользователи
Сообщений: 61
Пол: Мужской
Реальное имя: Илья

Репутация: -  0  +


у меня Code Gear 2009, будет и в 2010 компилиться
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 10.08.2025 3:56
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"