Программа "валится" на методе сортировки файла при записи - 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);
}

Объяснение кода листинга программы

  1. В функции Sort(char*name) происходит сортировка содержимого файла, который открывается для чтения и записи.
  2. Сначала определяется количество записей в файле с помощью fseek(fv,0,SEEK_END) и ftell(fv).
  3. Затем выделяется память для массива структур Record с помощью calloc(n,sizeof(Record)).
  4. Далее, в цикле for происходит чтение записей из файла в массив rec с помощью fread(&rec[i],sizeof(Record),1,fv).
  5. Каждая запись выводится на экран с помощью puts(rec[i].country).
  6. Далее, происходит сортировка массива rec с помощью qsort(rec,n,sizeof(Record),cmp).
  7. После сортировки, записи снова выводятся на экран с помощью puts(rec[i].country).
  8. Затем, отсортированные записи записываются обратно в файл с помощью fwrite(&rec[i],sizeof(Record),1,fv).
  9. В конце, память освобождается с помощью free(rec), файл закрывается с помощью fclose(fv).
  10. Если в процессе выполнения программы происходит ошибка, то выводится сообщение об ошибке и программа завершается с помощью printf(Error open file!\n); exit(-1);.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 3.833 из 5
Похожие ответы