Программа "валится" на методе сортировки файла при записи - C (СИ)

  1. Доброго времени суток! Есть вот такая вот программка. Валится на методе сортировки файла при записи в el58.dat. Не найду где. По условиям задания надо: 1)страна в 1958 выработала больше всех энергии; 2)страны которые в 1955 выработали больше 70 млрд; 3) отсортировать по алфавиту страны которые в 1958 не превысили производство 100 млрд. Вот на третьем и валится. Можно посмотреть исправленный вариант?C1 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] А у самого мозгов не хватает исправить ошибку.


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. Пытаюсь сделать простейший стек, программа сегфолтится при попытке обратиться к функции pop().C1 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 #include #define MAX 100   char *myStack[MAX]; int top = 0;   void push(char*); const char* pop(void);   int main(int argc, char **argv) {     push("fff");     printf("%s\n", pop());     return 0; }   void push(char *str) {     if (top < MAX)         myStack[top++] = str; }   const char* pop(void) {     if (top >= 0)         return myStack[top--];     return 0; }Где я ошибаюсь?

  1. Написать программу вывода элементов одномерного массива при наличии чисел заглушек и с правильным порядком индексации C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include #include     int main(){     int a[10] = {-1, 7, 1, 3, 1, -1, 4, -1, 6, 5 };   int  i = 0;               for(i = 0; i < sizeof(a)/ sizeof(*a); ++i)            if (a[i] != -1 )    printf ("a[%d]= %d\n", i, a[i]);    return 0; }Помогите вывести правильную индексацию массива

  1. Есть проблема если я беру "с=0" и в цикле пишу условие "с!=100", то у меня нормально отображается квадрат из звездочек, а если начинаю считать от 1 (с=1), тогда у меня в первой строке последней звездочки нет и она переносится после десятой строки, хотя этого быть не должно. Скажите, что не так в коде, расположенном в комментариях.C1 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 #include   main (void) {     int c=0, t;         while(c!=100)     {         c=c+1;         t=c%10;         printf("*");         if(t==0)         {             printf("\n");         }     }     printf("\n");     return 0; } /* ???? #include   main (void) {     int c=1, t;         while(c!=101)     {         c=c+1;         t=c%10;         printf("*");         if(t==0)         {             printf("\n");         }     }     printf("\n");     return 0; } */

  1. Буду благодарен, если кто-то объяснит, как работает данная программа построчно (отлично будет, если написать комментарии к каждой строке (кроме самых очевидных)), либо напишет программу попроще. Задача была следующая: напишите функцию expand(s1,s2), которая бы разворачивала сокращенную запись наподобие a-z в строке s1 в полный список abc...xyz в строке s2. Учитывайте буквы в любом регистре, цифры, а также записи вида a-b-c, a-z0-9 и -a-z. Сделайте так, чтобы знаки - в начале и в конце строки воспринимались буквально, а не как символы развертывания. Спасибо.C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void expand(char s1[], char s2[]) {     int i, j, k;     k = 0;     for (i = 0; s1[i] != '\0'; i++)         if (s1[i] == '-')             if (i == 0 || s1[i+1] == '\0')                 s2[k++] = '-';             else                 for (j = s1[i-1]; j <= s1[i+1]; j++)                     s2[k++] = j;     s2[k] = '\0'; }   int main(void) {     char s1[] = "-a-z0-9d-f-";     char s2[128] = "";     expand(s1, s2);     printf("s1=%s\ns2=%s\n", s1, s2);     return 0; } }

  1. C1 2 3 4 5 6 7 8 #include #define STOP * int main() { char ch; while ((ch=getchar())!=STOP) putchar (ch); }

  1. У меня есть две структуры, с одинаковым кол-вом полей, но поля разного типа:C1 2 3 4 5 6 7 8 9 10 11 12 13 struct hat {     char s1[20], s2[20], s3[20] ; } shapka;   typedef struct monopolies {     char name[40];     int year;     float capital;   }monopolies; monopolies monopoly; //создаю тут структуру типа monopoliesЕсть функция для обработки "шапки": ( если что, это считывание шапки таблицы из файла, но это не важно)C1 2 3 4 5 6 7 8 9 10 11 void Read_Shapka_File(FILE *f, struct hat *shapka) //как вы видите, отдаю в ф-ию указатель на структуру типа hat {     if (fscanf(f, "%s%s%s", shapka->s1, shapka->s2, shapka->s3)!=EOF)     {         printf("%-20s %15s %20s\n\n", shapka->s1, shapka->s2, shapka->s3);     }     else     {         exit(ERROR_READING_FILE);     } }...И совершенно другая, отдельная ф-ия, в которую я отдаю указатель на вторую структуру.C1 void Job1_Two_Files(char* putInp, monopolies *monopoly)В этой ф-ии я вызываю ф-ию Read_Shapka_File, но отдаю ей указатель на другую структуру, не ту, что положено:C1 Read_Shapka_File(inp, monopoly);. Мало того что компилятор не ругается, но программа работает и выводит-таки эту "шапку". КАК??? Если это из-за указателей в обеих ф-иях, это не объясняет, почему нет конфликта типов. Скидываю программу, постарался удалить все, что не относится к данной проблеме

  1. Создать программу, которая будет запрашивать у пользователя длины сторон треугольника. После этого программа должна вывести на экран периметр треугольника, площадь и углы, для которых нужно разработать функции. Площадь треугольника можно найти по формуле Герона. Углы можно найти по соотношению сторон. При выполнении программы все приглашения на ввод данных, а также все выводимые данные должны иметь четкое объяснение на экране.C1 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 #include #include #include   double SemiPerimeter(double a, double b, double c) {         double sPerimeter = (a + b + c) / 2;         return sPerimeter; }   double Square(double a, double b, double c, double SemiPerimeter) { double Square_Geron = sqrt(SemiPerimeter*(SemiPerimeter - a)*(SemiPerimeter - b)*(SemiPerimeter - c));         return Square_Geron; }   double AngleA(double a, double b, double c) {         double Angle_CosA = cos((a*a - b*b + c*c) / 2*(b*c));         return Angle_CosA; }   double AngleB(double a, double b, double c) {         double Angle_CosB = cos((a*a - b*b + c*c) / 2 * (a*c));         return Angle_CosB; } double AngleC(double a, double b, double c) {         double Angle_CosC = cos((a*a - b*b + c*c) / 2 * (a*b));         return Angle_CosC; }   main() {         SetConsoleCP(1251);         SetConsoleOutputCP(1251);             double Square_of_triangle, a, b, c;         double CosA, CosB, CosC;           printf("Введите сторону a: ");         scanf_s("%lf", &a);         printf("Введите сторону b: ");         scanf_s("%lf", &b);         printf("Введите сторону c: ");         scanf_s("%lf", &c);             Square_of_triangle = Square(a, b, c, SemiPerimeter(a, b, c));         printf("\tПлоща треугольника за формулою Герона: %f\n\n", Square_of_triangle);         CosA = AngleA(a, b, c);         printf("Кyт a равняется:  %f\n", CosA);         CosB = AngleB(a, b, c);         printf("Кyт b равняется:  %f\n", CosB);         CosC = AngleC(a, b, c);         printf("Кyт c равняется: %f\n", CosC);  }Проблема заключается в следующем, программа не правильно высчитывает углы, получается что углы не равны 180градусам. Подскажите что поменять в программе. Во-вторых, как можно оптимизировать, что бы не повторять одни и те же действия 3 раза. Зарание СПАСИБО!

  1. Нужна помощ в разработке программы по перекодировке текстовых файлов из кодового набора кои-8 в кодовый набор ср1251 по таблице, заданной в текстовом файле. Имя файла таблицы вместе с именем файлов исходного текста и результата его перекодировки должно передаваться программе через аргументы командной строки её вызова. Данные в таблице перекодировки должны быть представлены в системе счисления по основанию 8. Дело в том что я не могу понять как это представить в восьмеричной системе счисления

  1. Нужно чтобы программа вставляла в текст пробелы. но вместо них она у меня вставляет $. пробовал и через putchar(" ") и putchar("\t") - одно и тоже. как правильно выводить пробел на си?

  1. Вот программа, я не пониvаю как работает она с файлом. я запускаю ее, она как будто закончила работу и ничего не выводит. файл 123 находится на диске D. Может я что-то не так делаю? помогите пожалуйста разобратьсяC++1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include #include int main() { FILE *f;   char txt[20][10];   int j=0,i;   f=fopen("D:\123.txt","r");   fgets(txt[i],80,f);   while (feof(f))          {          for (j=0; j