Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 09.01.2012
Сообщений: 4
1

Программа "валится" на методе сортировки файла при записи

09.01.2012, 22:47. Показов 1157. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток!
Есть вот такая вот программка. Валится на методе сортировки файла при записи в el58.dat. Не найду где.
По условиям задания надо:
1)страна в 1958 выработала больше всех энергии;
2)страны которые в 1955 выработали больше 70 млрд;
3) отсортировать по алфавиту страны которые в 1958 не превысили производство 100 млрд.
Вот на третьем и валится. Можно посмотреть исправленный вариант?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#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);
}
Добавлено через 25 минут
Иными словами, оно должно выглядеть примерно так:
[404]
а выглядит вот так(падает как раз на моменте сортировки):
[404]

А у самого мозгов не хватает исправить ошибку.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.01.2012, 22:47
Ответы с готовыми решениями:

Программа валится при освобождении памяти под динамический массив
Доброго времени суток. Проблема такая. Моя программа представляет собой поразрядную сортировку даты...

почему программа валится?
using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

Программа валится с кодом -1073740940
Доброе время суток! Прошу помочь. При запуске программы программа не считает и переменная res= nan,...

Ошибка в методе при сохранении файла
Пытаюсь сохранить контейнер в файл, но выводит ошибку в классе tHouse на строчке 86. Понять не...

Программа валится из-за неправильного кода, в чем ошибка?
package com.example.ftmv1; import android.app.Activity; import android.os.Bundle; import...

7
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
09.01.2012, 23:59 2
из того что быстро увидел:
1)
Цитата Сообщение от test_file Посмотреть сообщение
if ((fv = fopen(name,"r+w")) == NULL)
верно писать r+ либо w+, если w+ то файл-поинтер уже на конце.

2)

вы в бинарном виде работаете? почему тогда режимы текстовые? надо писать rb, wb, rb+...

3)
Цитата Сообщение от test_file Посмотреть сообщение
fseek(fv,0,SEEK_SET);
n = ftell(fv)/sizeof(a); //Определение количества записей в файле
на начале файла стоишь.

по остальному:
я думаю метод сортировки напрямую в файле не самый лучший вариант. более того, я 1ый раз вижу чтобы так делали. хы-хы.
читай в массив структур их сортируй и пиши обратно, проще будет.
1
0 / 0 / 0
Регистрация: 09.01.2012
Сообщений: 4
10.01.2012, 00:02  [ТС] 3
Цитата Сообщение от OstapBender Посмотреть сообщение
верно писать r+ либо w+, если w+ то файл-поинтер уже на конце.
Уже поисправлял в коде.

Цитата Сообщение от OstapBender Посмотреть сообщение
я думаю метод сортировки напрямую в файле не самый лучший вариант. более того, я 1ый раз вижу чтобы так делали. хы-хы.
читай в массив структур их сортируй и пиши обратно, проще будет.
Не можете исправить что да как? Я же говорю, мозгов исправить не хватает.
Я теорию хоть немного понимаю, а в практике вообще дуб. Да и писал не совсем я.
0
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
10.01.2012, 00:23 4
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
0 / 0 / 0
Регистрация: 09.01.2012
Сообщений: 4
10.01.2012, 19:19  [ТС] 5
Самое интересное, что этап сортировки как бы проходит, и доходит до дела вывода стран в которых электричество меньше 100, но сортировка всё равно растянутая на пол программы.

Добавлено через 1 минуту
Упс, вроде работает как надо... сейчас кое-что попробую доисправлять и отпишусь.

Добавлено через 10 минут
Всё, огромное спасибо! Работает как и надо.

Добавлено через 18 часов 37 минут
А можете подсказать про код в программе, который отвечает за сортировку?
Сейчас сортирует по алфавиту. А если в обратном алфавитном, например? Мне сказали что отвечает strcmp и какое значение(>0, =0, <0) он вернёт - так и будет сортироваться.
Тут я такого не нашёл.
Не подскажите, пожалуйста?
0
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
10.01.2012, 20:00 6
сортирует функция qsort.
http://www.cplusplus.com/refer... lib/qsort/

Цитата Сообщение от test_file Посмотреть сообщение
А если в обратном алфавитном, например?
C
1
2
3
int cmp(const void * a, const void * b) {
        return -strcmp(((Record*)a)->country,((Record*)b)->country);
}
Цитата Сообщение от test_file Посмотреть сообщение
Мне сказали что отвечает strcmp и какое значение(>0, =0, <0) он вернёт - так и будет сортироваться.
ну вообще важно возвращаемое значение функции cmp, но т.к она повторяет по сути результат strcmp, то можно и так сказать.
1
0 / 0 / 0
Регистрация: 09.01.2012
Сообщений: 4
10.01.2012, 20:04  [ТС] 7
Цитата Сообщение от OstapBender Посмотреть сообщение
ну вообще важно возвращаемое значение функции cmp, но т.к она повторяет по сути результат strcmp, то можно и так сказать.
Т.е. можно смело сказать что тут отыгрывает роль strcmp - cmp.
Спасибо большое.
0
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
10.01.2012, 20:10 8
test_file, Наоборот.
cmp - функция сравнения указателей (в данном случае на структуру),
т.к в условии было дано сравнивать по имени (char*), то я использовал strcmp.
В данном (и только данном) случае роль функции сравнения выполняет strcmp.
1
10.01.2012, 20:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.01.2012, 20:10
Помогаю со студенческими работами здесь

Задача про вычисление арифметических выражений. Необходимо найти пример на котором валится программа
По статье В. А. Матюхина &quot;Подсчет значения арифметического выражения методом рекурсивного спуска&quot;...

Программа сортировки (по возрастанию) файла, содержащего целые числа
var f1,f2:text; st:string; x:char; i,j:integer; el:boolean; procedure...

На каком методе сортировки стоит остановиться ?
Добрый день друзья ! Изучаю Паскаль и столкнулся с четырьмя способами сортировки массива : 1)...

Валится приложение при объявлении связи
Доброго времени суток. Имеется проект на Objective c. Есть контроллер с элементом tableView и есть...

При удалении пользователя валится сервер
при удалении пользователя были выставлены следующие флаги: • Delete the mail database on the...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru