Программа "валится" на методе сортировки файла при записи - C (СИ)
Формулировка задачи:
Доброго времени суток!
Есть вот такая вот программка. Валится на методе сортировки файла при записи в el58.dat. Не найду где.
По условиям задания надо:
1)страна в 1958 выработала больше всех энергии;
2)страны которые в 1955 выработали больше 70 млрд;
3) отсортировать по алфавиту страны которые в 1958 не превысили производство 100 млрд.
Вот на третьем и валится. Можно посмотреть исправленный вариант?
#include "stdafx.h" #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> //--------------Прототипы функций------------------ void fileInput(); //Формирование файла void fileOutput(char*); //Вывод файла void max58(); //Вывод максимального оборота void form55(); //Формирование файла со страними с экспортом болеее 900 void form58(); //Формирование файла со страними с импортом менее 1000 void Sort(char*); //Сортировка файла //------------Глобальные переменные --------------- struct Record { //структуры данных char country[20]; //Название страны float el55; //Произведено электроэнергии в 1955 float el58; //в 1958 } a,b; FILE *fv, *f2; //Файлы прямого доступа //------------ Основная программа ---------------- int main(void) { int f; printf("Formirovat file? (1 - yes, 0 - no)\n"); scanf("%d",&f); if(f) fileInput(); fileOutput("data.dat"); max58(); form55(); printf("Strani, elektri4estdvo v kotorih bolshe 70 mld v 1955\n"); fileOutput("el55.dat"); form58(); Sort("el58.dat"); printf("Strani, elektri4estdvo v kotorih bolshe 100 mld v 1958\n"); fileOutput("el58.dat"); getch(); } //--------- Реализация функций --------------------- void fileInput() { float f; if ((fv = fopen("data.dat","w")) == NULL)//Открытие файла для записи { printf("Error open file!\n"); exit(-1); } strcpy(a.country,"a"); while (strcmp(a.country,"0")!=0) //Ввод записей пока вместо найвания страны не введен 0 { printf("Enter country <<0 - exit>>\n"); scanf("%s",a.country); //Ввод названия страны if (strcmp(a.country,"0")!=0) { printf("Enter koli4estvo v 1955\n");//Ввод электрических параметров страны scanf("%f",&f); a.el55 = f; printf("Enter koli4estvo v 1958\n"); scanf("%f",&a.el58); fwrite(&a,sizeof(a),1,fv); //Запись структуры в файл } } printf("Data is writen\n"); fclose(fv); //Закрытие файла } void fileOutput(char* name) { int uk,i; if ((fv = fopen(name,"r")) == NULL) //Открытие файла для чтения { printf("Error open file!\n"); exit(-1); } fseek(fv,0,SEEK_END); uk = ftell(fv); //Определание размера файла i = 0; //начальная позиция файла printf("-----------------------------------\n"); printf("! country !1955 !1958 !\n"); printf("-----------------------------------\n"); while (i<uk) //Пока не достигнут конец файла { fseek(fv,i,SEEK_SET); //Установка указателя на текущую позицию fread(&a,sizeof(a),1,fv); //Чтение текущей структуры из файла printf("!%20s !%5.1f!%5.1f!\n", a.country,a.el55,a.el58); //вывод на экран i += sizeof(a); //Перевод указателя на следующую структуру } printf("-----------------------------------\n"); fclose(fv); //Закрытие файла } void max58() { int uk,i; float max; if ((fv = fopen("data.dat","r")) == NULL)//Открытие файла для чтения { printf("Error open file!\n"); exit(-1); } fseek(fv,0,SEEK_END); uk = ftell(fv); //Определание размера файла i = 0; //начальная позиция файла while (i<uk) //Пока не достигнут конец файла { fseek(fv,i,SEEK_SET); //Установка указателя на текущую позицию fread(&a,sizeof(a),1,fv); //Чтение текущей структуры из файла if (i==0) //Если тек. структура пермая max = a.el58-1; //максимуму присваивается заведомо меньшее значение if (a.el58>max) //количество электроэнерии больше максимального { max = a.el58; //Обновление максимального strcpy(b.country,a.country); //Копирование структуры b.el55 = a.el55; b.el58 = a.el58; } i += sizeof(a); //Перевод указателя на следующую структуру } fclose(fv); //Закрытие файла printf("max v 1958 - %5.1f (%s)\n",b.el58,b.country);//Вывод результата на экран } void form55() { int uk,i; if ((fv = fopen("data.dat","r")) == NULL)//Открытие файла для чтения { printf("Error open file!\n"); exit(-1); } if ((f2= fopen("el55.dat","w"))== NULL)//Открытие файла для записи { printf("Error open file!\n"); exit(-1); } fseek(fv,0,SEEK_END); uk = ftell(fv); //Определание размера файла i = 0; //начальная позиция файла while (i<uk) //Пока не достигнут конец файла { fseek(fv,i,SEEK_SET); //Установка указателя на текущую позицию fread(&a,sizeof(a),1,fv); //Чтение текущей структуры из файла if (a.el55>70) //Если кол-во эл. в 1955 больше 70 { fwrite(&a,sizeof(a),1,f2); //запись структуры во второй файл } i += sizeof(a); //Перевод указателя на следующую структуру } fclose(fv); //Закрытие исходного файла fclose(f2); //Закрытие второго файла } void form58() { int uk,i; if ((fv = fopen("data.dat","r")) == NULL)//Открытие файла для чтения { printf("Error open file!\n"); exit(-1); } if ((f2= fopen("el58.dat","w")) == NULL) //Открытие файла для записи { printf("Error open file!\n"); exit(-1); } fseek(fv,0,SEEK_END); uk = ftell(fv); //Определание размера файла i = 0; //начальная позиция файла while (i<uk) //Пока не достигнут конец файла { fseek(fv,i,SEEK_SET); //Установка указателя на текущую позицию fread(&a,sizeof(a),1,fv); //Чтение текущей структуры из файла if (a.el58<100) //Если кол-во эл. в 1958 меньше 100 { fwrite(&a,sizeof(a),1,f2); //запись структуры во второй файл } i += sizeof(a); //Перевод указателя на следующую структуру } fclose(fv); //Закрытие исходного файла fclose(f2); //Закрытие второго файла } void Sort(char*name) { int i=0, j, pos,n; if ((fv = fopen(name,"r+w")) == NULL) //Открытие файла для чтения и записи { printf("Error open file!\n"); exit(-1); } fseek(fv,0,SEEK_SET); n = ftell(fv)/sizeof(a); //Определение количества записей в файле while (i<(sizeof(a)*(n-1))) //Пересмотр всех записей кроме последней { fseek(fv,i,SEEK_SET); fread(&a,sizeof(a),1,fv); j = i+sizeof(a); while (j<(sizeof(a)*n)) //Просмотр всех записей кроме уже отсортированых { fseek(fv,j,SEEK_SET); fread(&b,sizeof(b),1,fv); if (strcmp(a.country,b.country)>0)//Сравнение названий стран { pos = i; fseek(fv,pos,SEEK_SET); fwrite(&b,sizeof(b),1,fv); //Запись структуры b вместо а pos = j; fseek(fv,pos,SEEK_SET); fwrite(&a,sizeof(a),1,fv); //Запись структуры а вместо b strcpy(a.country,b.country); a.el55 = b.el55; //Копирование структуры b в а a.el58 = b.el58; } j += sizeof(b); } i += sizeof(a); } fclose(fv); }
Иными словами, оно должно выглядеть примерно так:
[404]
а выглядит вот так(падает как раз на моменте сортировки):
[404]
А у самого мозгов не хватает исправить ошибку.
Решение задачи: «Программа "валится" на методе сортировки файла при записи»
textual
Листинг программы
int cmp(const void * a, const void * b) { return strcmp(((Record*)a)->country,((Record*)b)->country); } void Sort(char*name) { int i=0, j, pos,n; if ((fv = fopen(name,"rb+")) == NULL) //Открытие файла для чтения и записи { printf("Error open file!\n"); exit(-1); } fseek(fv,0,SEEK_END); n = ftell(fv)/sizeof(a); //Определение количества записей в файле printf("\n\n\n N = %d \n\n\n",n); Record * rec = (Record*)calloc(n,sizeof(Record)); puts("\n\nDEBUG:\n\n\n\n"); fseek(fv,0,SEEK_SET); for (i=0; i<n; i++) { fread(&rec[i],sizeof(Record),1,fv); puts(rec[i].country); } qsort(rec,n,sizeof(Record),cmp); fseek(fv,0,SEEK_SET); puts("\n\nDEBUG SORTED:\n\n\n\n"); for (i=0; i<n; i++) { puts(rec[i].country); fwrite(&rec[i],sizeof(Record),1,fv); } puts("\n\n"); free(rec); fclose(fv); }
Объяснение кода листинга программы
- В функции
Sort(char*name)
происходит сортировка содержимого файла, который открывается для чтения и записи. - Сначала определяется количество записей в файле с помощью
fseek(fv,0,SEEK_END)
иftell(fv)
. - Затем выделяется память для массива структур
Record
с помощьюcalloc(n,sizeof(Record))
. - Далее, в цикле
for
происходит чтение записей из файла в массивrec
с помощьюfread(&rec[i],sizeof(Record),1,fv)
. - Каждая запись выводится на экран с помощью
puts(rec[i].country)
. - Далее, происходит сортировка массива
rec
с помощьюqsort(rec,n,sizeof(Record),cmp)
. - После сортировки, записи снова выводятся на экран с помощью
puts(rec[i].country)
. - Затем, отсортированные записи записываются обратно в файл с помощью
fwrite(&rec[i],sizeof(Record),1,fv)
. - В конце, память освобождается с помощью
free(rec)
, файл закрывается с помощьюfclose(fv)
. - Если в процессе выполнения программы происходит ошибка, то выводится сообщение об ошибке и программа завершается с помощью
printf(
Error open file!\n); exit(-1);
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д