Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.05.2015, 00:25   #1
Pug_from_Mordor
Пользователь
 
Аватар для Pug_from_Mordor
 
Регистрация: 09.11.2014
Сообщений: 40
Печаль Работа с бинарными файлами в СИ.

Здравствуйте, нужна помощь в курсаче. Задание: написать базу данных ж/д вокзала.
Для этого я использовал последовательный список.
Вот эта структура.
Код:
typedef struct VOKZAL{
	int nomer_poezda,chislo_vagonov,kolichestvo_mest;
	TIMEE otpravka;
	TIMEE pribytie;
    }VOKZAL;
typedef struct LIST{
	int razmer;
	VOKZAL *vokzal; 
    }LIST;
Вот функция записи
Код:
int Save( LIST *List)
{
   FILE *Stream = fopen("base.txt", "wb" );

   if ( !Stream )
      return 1;
   for ( int Index = 0; Index < List->razmer ; Index++ )
   {
      if ( !fwrite( &List->vokzal[Index], sizeof( VOKZAL ), 1, Stream ) )
         return 1;
   }
   fclose( Stream );
   return 0;
}
Вот функция считывания
Код:
int Load( LIST *List)
{

   int i=0;
   VOKZAL Item[20];
   FILE *Stream;

   Stream=fopen("base.txt", "rb" );

   if(!Stream)
      return 1;

   destroy(List); 

   while( !feof( Stream ) )
   {
	   i++;
     
    if(!fread(&Item[i-1], sizeof(VOKZAL), 1, Stream ))
       break;
    List->razmer=i-1;

    add(List,Item[i-1]);
   }

   printf("Считано %d элементов\n",i-1);
   fclose(Stream);

   return 0;
}
функция destroy просто освобождает дин память выделенную под массив и обнуляет его , а также поле razmer.
Функция add
Код:
int add(LIST *list,VOKZAL value)
{
	VOKZAL *tmp=(VOKZAL *)realloc(list->vokzal,(list->razmer+1)*sizeof(VOKZAL));

	if(!tmp)return 1;

	tmp[list->razmer]=value;
	list->vokzal=tmp;
	list->razmer++;

    return 0;
}
При загрузке в файл всё вроде работает, но когда считываю и вывожу на экран, показывает какой-то бред.
Вызов функций
Код:
case 12:if(Save(list)!=0)printf("Ошибка !\n");else printf("Запись в файл прошла успешно\n");break;
	  case 13:if(Load(list)!=0)printf("Ошибка !\n");else printf("Чтение из файла прошло успешно\n");break;

Последний раз редактировалось Stilet; 26.05.2015 в 12:24.
Pug_from_Mordor вне форума Ответить с цитированием
Старый 26.05.2015, 01:52   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Поскольку не знаю, что такое TIMEE, то выбросил эти поля из структуры. Заполнил лист информацией о 2 вокзалах, сохранил, загрузил и напечатал - ошибок нет. Думаю, что тип TIMEE работает с указателями, из-за этого проблемы.

А еще мне не понравилось:
Код:
List->razmer=i-1;
add(List,Item[i-1]);
Увеличивайте размер сразу в функции Add. Также часто используется следующий метод: задаётся начальный размер списка (например, 20), и при необходимости размер увеличивается во сколько-то раз (например, в 2), а не по 1 элементу. Траты памяти увеличатся, но операция realloc достаточно "дорогая", чтобы вызывать её для добавления каждого элемента.

Код:
VOKZAL Item[20];
...
if(!fread(&Item[i-1], sizeof(VOKZAL), 1, Stream ))
Почему не завести одну временную переменную?
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 26.05.2015, 12:03   #3
Pug_from_Mordor
Пользователь
 
Аватар для Pug_from_Mordor
 
Регистрация: 09.11.2014
Сообщений: 40
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
А еще мне не понравилось:
Код:
List->razmer=i-1;
add(List,Item[i-1]);
Увеличивайте размер сразу в функции Add.
А ну да. первая строчка вообще лишняя.
Pug_from_Mordor вне форума Ответить с цитированием
Старый 27.05.2015, 20:01   #4
Pug_from_Mordor
Пользователь
 
Аватар для Pug_from_Mordor
 
Регистрация: 09.11.2014
Сообщений: 40
По умолчанию

Спасибо, заменил массив на переменную, убрал строку и всё заработало. Но вот недавно запустил программу и почему-то перестала работать функция system("cls").
Вот мой main.
Код:
setlocale(LC_ALL,"RU");

    int action=1,i=0,position=0;
    LIST *list=(LIST *)malloc(sizeof(LIST)); 

    creat(list);             

    if(Load(list)!=0)
		printf("База данных не найдена\n");
	else 
		printf("Чтение базы данных прошло успешно\n");

	   printf("Нажмите Enter для продолжения\n");
       fflush(stdin);
	   getchar();
       system("cls");
                 
    do
	{
		printf("===Добавление===\n");
		printf("1 Добавить в конец списка\n");
		printf("2 Добавить в указанную позицию\n");
		printf("===Удаление===\n");
		printf("3 Удаление элемента по позиции\n");
		printf("4 Удаление всего списка\n");
		printf("===Дополнительные функции===\n");
		printf("5 Вывод списка\n");
		printf("6 Редактирование элемента в списке\n");
		printf("7 Поиск в списке по номеру поезда \n");
		printf("8 Сортировка по дате отпраки\n");
		printf("9 Сортировка по дате прибытия\n");
		printf("10 Сортировка по номеру поезда\n");
		printf("11 Сортировка по количеству вагонов[количеству мест]\n");
		printf("===Работа с файлом===\n");
		printf("12 Cохранение в файл base.txt\n");
		printf("13 Чтение из файла base.txt\n");
		printf("0.Выход\n");
	
		fflush(stdin);
	   scanf("%d",&action);
    
	   switch(action)
	   {
          case 1:if(add(list,input())!=0)printf("Ошибка!\n");break; 
	      case 2:printf("Введите место на которое надо вставить элемент\n");
scanf("%d",&position);
while(addmid(list,input(),position)!=0){printf("Ошибка ввода!\n Введите место на которое надо вставить элемент\n");
scanf("%d",&position);}break;
	      case 3:printf("Введите номер элемента который надо удалить\n");
scanf("%d",&position);
while(del(list,position)!=0){printf("Ошибка ввода!\nВведите номер элемента который надо удалить\n");
scanf("%d",&position);}break;
	      case 4:printf("Вы уверены что хотите удалить ВЕСЬ список?[1-продолжить,0-прервать]\n");
scanf("%d",&position);
if(!position){printf("Удаление отменено\n");break;}else{destroy(list);printf("Удаление произошло успешно\n");}break;
		  case 5:for(i=0;i<list->razmer;i++){printf("=========================================\n");
printf("Информация о %d-м поезде\n",i+1);output(list->vokzal[i]);}break;
	      case 6:for(i=0;i<list->razmer;i++){printf("=========================================\n");
printf("Информация о %d-м поезде\n",i+1);output(list->vokzal[i]);}printf("Введите номер элемента который надо отредактировать\n");
scanf("%d",&position);
while(edit(list,input(),position)!=0){printf("Ошибка!\nВведите номер элемента который надо отредактировать\n");;
scanf("%d",&position);}
break;
	      case 7:search(list);break;
		  case 8:if(sort_otpravka(list)!=0)printf("Список пуст!\n");else printf("Сортировка выполнена успешно\n");break;
		  case 9:if(sort_pribytie(list)!=0)printf("Список пуст!\n");else printf("Сортировка выполнена успешно\n");break;
		  case 10:if(nomer_poezda_sort(list)!=0)printf("Список пуст\n");else printf("Сортировка выполнена успешно\n");break;
		  case 11:if(chislo_vagonov_sort(list)!=0)printf("Список пуст\n");else printf("Сортировка выполнена успешно\n");break;
		  case 12:if(Save(list)!=0)printf("Ошибка !\n");else printf("Запись в файл прошла успешно\n");break;
		  case 13:if(Load(list)!=0)printf("Ошибка !\n");else printf("Чтение из файла прошло успешно\n");break;
   	   }

	   if(action)
	   {
	       printf("Нажмите Enter для продолжения\n");

           fflush(stdin);
	       getchar();
		   system("cls");
	   }
    }while(action!=0);

	free(list);
    
	return 0;

Последний раз редактировалось Stilet; 27.05.2015 в 20:21.
Pug_from_Mordor вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с бинарными файлами SoTwisted Помощь студентам 0 25.04.2011 01:59
С# работа с бинарными файлами bondik Общие вопросы .NET 1 01.10.2010 12:18
работа с бинарными файлами klykovka Помощь студентам 7 28.04.2010 11:07
Работа с бинарными файлами StudentPolitech Общие вопросы C/C++ 0 19.05.2009 23:48