Сформировать массив структур из уже созданных - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Составил программку которая успешно работает: создает бинарный файл со структурой, просматривает и решает поставленную задачу (рассчитать надбавку к стипендии в зависимости от успеваемости). Всё хорошо работает и все условия проходят, кроме одного: никак не могу заставить ее считать надбавку ТОЛЬКО для студентов определенной группы номер которой надо ввести с клавиатуры. По идее надо так: пробегаюсь по общему уже созданному массиву структур и сравниваю через strcmp поле student.nomer (номер группы). Если 0, то формирую новый массив структур. Затем надо выполнить задачу, но только для этих структур. А у меня считается для всех групп и нет разницы, что я ввожу только 2-ю или например 5-ю группу для расчета. Может кто подскажет как исправить? Какие строки надо дописать? Я так понимаю не формируется нужный массив структур для расчета. Код *.cpp в спойлере. Проблема в case 4. Бинарный файл в прикрепленном архиве.
/*
Создать программу (выполнив функциональное разбиение) реализующую следующие функции работы с бинарным файлом.
Предусмотреть создание меню со следующими пунктами:
1 – СОЗДАНИЕ НОВОГО ФАЙЛА  
2 – ПРОСМОТР ФАЙЛА 
3 – КОРРЕКТИРОВКА ЗАПИСЕЙ ФАЙЛА (изменение, добавление новой записи, удаление записи)
4 – ВЫПОЛНЕНИЕ ЗАДАЧИ 
5 – ВЫХОД
 
Создать файл, содержащий сведения о результатах сдачи студентами сессии.
Структура записи:
номер группы, ФИО, оценки по 3 предметам, признак участия в общественной работе: 1 –  участие, 0 – неучастие.
 
ПРОГРАММА ДОЛЖНА НАЧИСЛЯТЬ СТУДЕНТАМ ГРУППЫ Х (ввести с клавиатуры)
СТИПЕНДИЮ. ПРИ ЭТОМ СТУДЕНТ ОТЛИЧНИК И ОБЩЕСТВЕННИК ПОЛУЧАЕТ 50% НАДБАВКУ К БАЗОВОЙ СТИПЕНДИИ,
ПРОСТО ОТЛИЧНИК – 25%, БЕЗ ТРОЕК – 10%. СТУДЕНТ ОБЩЕСТВЕННИК С ОДНОЙ ТРОЙКОЙ ТАКЖЕ ПОЛУЧАЕТ
СТИПЕНДИЮ С НАДБАВКОЙ 10%. НЕУСПЕВАЮЩИЕ СТУДЕНТЫ СТИПЕНДИЮ НЕ ПОЛУЧАЮТ. РЕЗУЛЬТАТ ОТСОРТИРОВАТЬ ПО ФАМИЛИИ.*/
 
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <locale.h>
#include <io.h>
#include <windows.h>
 
bool flag (void);
struct stipendia {
    char fio[20];
    char nomer[1];
    int pred1;
    int pred2;
    int pred3;
    int people;
    int zp;
};
 
void main ()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    FILE *money;
    FILE *temp;
    int select, select1;
    int p,n,u,j=0,k,i=0;
    int zp=0;
    struct stipendia student,temporary;
    char surname[20];
    char surname_del[20];
    char surnomer[1];
    setlocale(LC_CTYPE,"Russian");
    for (;;) {
        puts("\n\t\t\tМЕНЮ");
        puts("\t\t1 - Создание нового файла");
        puts("\t\t2 – Просмотр файла");
        puts("\t\t3 – Корректировка записей файла");
        puts("\t\t4 – Выполнение задачи");
        puts("\t\t5 – Выход");
        printf("Выберите  действие:  \r\n");
        scanf("%d",&select);
        fflush(stdin);
 
        switch (select) {
        case 1:
            if(!(money = fopen("stipendia.bin", "w+b"))) {
                printf("\t\tНевозможно открыть файл \n");
                return;
            }
            do {
                fflush(stdin);
                printf("\nВведите номер группы: "); scanf("%s",&student.nomer); fflush(stdin);
                printf("Введите фамилию студента: "); scanf("%s",&student.fio); fflush(stdin);
                printf("Оценка по 1-му предмету: "); scanf("%i",&student.pred1); fflush(stdin);
                printf("Оценка по 2-му предмету: "); scanf("%i",&student.pred2); fflush(stdin);
                printf("Оценка по 3-му предмету: "); scanf("%i",&student.pred3); fflush(stdin);
                printf("Участие в общественной работе 1-Да / 0-Нет: "); scanf("%i",&student.people);
                if(student.people<0||student.people>1) {
                    printf("Неверное значение!\n");
                    student.people=0;           }
                fflush(stdin);
                fwrite (&student,sizeof(student),1,money);
                printf("\t\tПродолжить ( д / н )?");
            }
            while (flag()!=true);
            fclose(money); 
            break;
 
        case 2:
            if(!(money = fopen("stipendia.bin", "r+b"))) {printf("\t\tНевозможно открыть файл \n"); return; }
            while (fread(&student,sizeof(student),1,money)) {
                if (feof(money)) break;
                printf("#%s %s\t%i %i %i %i\n",student.nomer, student.fio, student.pred1,student.pred2,student.pred3, student.people);
            }
            fclose (money);
            break;
        case 3:
            puts("\n\t\t\tВЫБЕРИТЕ КОМАНДУ");
            puts("\t\t1 - Изменить запись");
            puts("\t\t2 – Добавить запись");
            puts("\t\t3 – Удалить запись");
            scanf("%d",&select1); fflush(stdin);
            
            switch (select1) {
            case 1:
                if(!(money = fopen("stipendia.bin", "r+b"))) {printf("\t\tНевозможно открыть файл \n"); return; }
                printf("Введите фамилию для изменения: "); fflush(stdin);
                gets(surname);
                fread(&student,sizeof(student),1,money);
                while (!feof(money)) {
                    if (strcmp(student.fio,surname)==0) {
                        printf("#%s %s\t%i %i %i %i\n",student.nomer,student.fio,student.pred1,student.pred2,student.pred3,student.people);
                        printf("\t\tИзменить? ( д / н )");
                        if (flag()!=true) {
                            fflush(stdin);
                            printf("\nВведите номер группы: "); scanf("%s",&student.nomer); fflush(stdin);
                            printf("Введите фамилию студента: "); scanf("%s",&student.fio); fflush(stdin);
                            printf("Оценка по 1-му предмету: "); scanf("%i",&student.pred1); fflush(stdin);
                            printf("Оценка по 2-му предмету: "); scanf("%i",&student.pred2); fflush(stdin);
                            printf("Оценка по 3-му предмету: "); scanf("%i",&student.pred3); fflush(stdin);
                            printf("Участие в общественной работе 1-Да / 0-Нет: "); scanf("%i",&student.people);
                            if(student.people<0||student.people>1) {
                                printf("Неверное значение!\n");
                                student.people=0;           }
                            fflush(stdin);
                            p=sizeof(student);
                            fseek(money,-p,1); 
                            fwrite(&student,sizeof(student),1,money);
                                break;
                        }
                    }
 
                    fread(&student,sizeof(student),1,money);
                }
                fclose (money);
                break;
            case 2:
                if(!(money = fopen("stipendia.bin", "a+b"))) {printf("\t\tНевозможно открыть файл \n"); return; }
                do {
                    fflush(stdin);
                    printf("\nВведите номер группы: "); scanf("%s",&student.nomer); fflush(stdin);
                    printf("Введите фамилию студента: "); scanf("%s",&student.fio); fflush(stdin);
                    printf("Оценка по 1-му предмету: "); scanf("%i",&student.pred1); fflush(stdin);
                    printf("Оценка по 2-му предмету: "); scanf("%i",&student.pred2); fflush(stdin);
                    printf("Оценка по 3-му предмету: "); scanf("%i",&student.pred3); fflush(stdin);
                    printf("Участие в общественной работе 1-Да / 0-Нет: "); scanf("%i",&student.people);
                    if(student.people<0||student.people>1) {
                        printf("Неверное значение!\n");
                        student.people=0;           }
                    fflush(stdin);
                    fwrite (&student,sizeof(student),1,money);
                    printf("\t\tПродолжить ( д / н )?");
 
                }
                while (flag()!=true);
                fclose (money);
                break;
            case 3:
                if(!(money = fopen("stipendia.bin", "r+b"))) {printf("\t\tНевозможно открыть файл \n"); return; }
                if(!(temp = fopen("temp.bin", "w+b"))) {printf("\t\tНевозможно открыть файл \n"); return; }
                printf("Введите фамилию для удаления: ");
                fflush(stdin);
                gets(surname_del);
                fread(&student,sizeof(student),1,money);
                while (!feof(money)) {
                    if (strcmp(student.fio,surname_del)!=0) {
                        fwrite(&student,sizeof(student),1,temp);
                        fread(&student,sizeof(student),1,money);
                    }
                    else fread(&student,sizeof(student),1,money);
                }
                fclose (money);
                remove ("stipendia.bin");
                fclose (temp);
                rename ("temp.bin","stipendia.bin");
                if(!(temp = fopen("stipendia.bin", "r+b"))) {printf("\t\tНевозможно открыть файл \n"); return; }
                while (fread(&student,sizeof(student),1,money)) {
                    if (feof(temp)) break;
                    printf("#%s %s\t%i %i %i %i\n",student.nomer, student.fio, student.pred1,student.pred2,student.pred3, student.people);
                }
                break;
            }
            break;
        case 4:
            if(!(money = fopen("stipendia.bin", "r+b"))) {printf("Невозможно открыть файл \n"); return; }
            
            //Ввод номера группы для расчета стипендии
            printf_s ("\nВведите номер группы для расчета надбавки к стипендии: "); fflush(stdin);
            gets(surnomer);
            fread(&student,sizeof(student),1,money);
            while (!feof(money)) {
                if (strcmp(student.nomer,surnomer)==0) {
 
            puts("\nБез сортировки: ");
            while(student.nomer)
            {
 
            //Расчет стипендии
            stipendia *sortirovka;
            fseek( money, 0, 2 );
            n = ftell(money) / sizeof(student);
            rewind(money);
            sortirovka=(stipendia*)malloc(n*sizeof(stipendia));
            for(i=0; i<n; i++) {
                fread(&student,sizeof(student),1,money);
                
                if (((student.pred1 & student.pred2 & student.pred3) >4) & student.people>0) {student.zp=50;}   //студент отличник и общественник + 50%
                if (((student.pred1 & student.pred2 & student.pred3) >4) & student.people<1) {student.zp=25;}   //просто отличник + 25%
                if (((student.pred1 & student.pred2 & student.pred3)>3 & (student.pred1 & student.pred2 & student.pred3)<5)  & (student.people>0 || student.people<1)) {student.zp=10;} //без троек + 10%
                if (( ((student.pred1>2 & student.pred1<4) & student.pred2>3 & student.pred3>3) || (student.pred1>3 & (student.pred2>2 & student.pred2<4) & student.pred3>3) || (student.pred1>3 & student.pred2>3 & (student.pred3>2  & student.pred3<4))) & student.people>0) {student.zp=10;}    //студент общественник с одной тройкой + 10%
                if (((student.pred1<4 & student.pred2>0 & student.pred3>0) || (student.pred1>0 & student.pred2<4 & student.pred3>0) || (student.pred1>0 & student.pred2>0 & student.pred3<4)) & (student.people>0  || student.people<1)) {student.zp=0;}    //неуспевающие студенты стипендию + 0%
                
                sortirovka[i]=student;
                printf("#%s %s\t%i %i %i %i\tНадбавка = %i%%\n",student.nomer, student.fio, student.pred1,student.pred2,student.pred3, student.people, student.zp);
            }
 
            //Сортировка по фамилии
            for(i=0; i<n; i++) {
                for(k=i; k<n-1 ; k++) {
                    if(strcmp(sortirovka[i].fio, sortirovka[k+1].fio) > 0) {
                        temporary = sortirovka[i];
                        sortirovka[i] = sortirovka[k+1];
                        sortirovka[k+1] = temporary;
                    }
                }
            }
 
            ////Сортировка по 1-й оценке
            //for(i=0; i<n; i++) {
            //  for(k=0; k<n-1 ; k++) {
            //      //OemToCharA(student.fio,(LPSTR)student.fio);
            //      if(sortirovka[k].pred1 < sortirovka[k+1].pred1) {
            //          temporary = sortirovka[k];
            //          sortirovka[k] = sortirovka[k+1];
            //          sortirovka[k+1] = temporary;
            //      }
            //  }
            //}
 
            puts("\nОтсортировано по фамилии: ");
            for(i=0; i<n; i++) {
                printf("#%s %s\t%i %i %i %i\tНадбавка = %i%%\n",sortirovka[i].nomer,sortirovka[i].fio, sortirovka[i].pred1,sortirovka[i].pred2,sortirovka[i].pred3, sortirovka[i].people, sortirovka[i].zp);
            }
 
            free(sortirovka);
            break;
            }
            break;
                }
            }
            fclose (money); break;
        case 5: exit(0);
        default: puts ( "Неверный выбор, нажмите любую клавишу"); _getch();
        }
    }
}
 
bool flag (void)
{
    char flag1;
    bool flag2=true;
    scanf("%c",&flag1);
    fflush(stdin);
    if (flag1!='Н' && flag1!='н') {
        flag2=false;
    }
    else flag2=true;
    return flag2;
}

Решение задачи: «Сформировать массив структур из уже созданных»

textual
Листинг программы
// если не-Windows то некоректная работа - виноват fflush(stdin).
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h> // если С++ - закоментировать.
#include <locale.h>
 
 
enum{ FIO_SIZE = 25 };
 
typedef struct Student {
    char fio[FIO_SIZE];
    int nomer;
    int pred1, pred2, pred3;
    bool people;
}Student;
 
typedef struct Stipendia{
    char fio[FIO_SIZE];
    int n;
}Stipendia;
 
Student* input_stud(Student *);
bool question(const char []);
int print_menu(void);
void create_file(const char []);
void print_file (const char []);
void corect_file(const char []);
void doing      (const char []);
 
 
// --------------   MAIN   --------------------------
int main(void){
    const char filename[] = "stipendia.bin";
    
    setlocale(LC_ALL, "Rus");
    
    for (;;){
        switch (print_menu()){
        case 1:  create_file(filename);  break;
        case 2:  print_file(filename);   break;
        case 3:  corect_file(filename);  break;
        case 4:  doing(filename);        break;
        case 5:  goto exit_from_menu;
        }
    }
    exit_from_menu:
    
    return EXIT_SUCCESS;
}
// ----------------   END MAIN   -----------------------
 
 
int  print_corect_menu(void);
void change_record(Student *, const int);
void add_record   (Student **, int *);
void delete_record(Student *, int *);
 
int compare(const void *, const void *);
 
 
int print_menu(void){
    printf("\n\t\tМЕНЮ\n");
    printf("\t1 - Создание нового файла\n");
    printf("\t2 – Просмотр файла\n");
    printf("\t3 – Корректировка записей файла\n");
    printf("\t4 – Выполнение задачи\n");
    printf("\t5 – Выход\n");
    printf("Выберите  действие: ");
    
    int n;
    scanf("%d",&n);
    
    fflush(stdin);
    
    return n;
}
 
 
Student* input_stud(Student *stud){
    
    printf("\nВведите фамилию студента: ");  fgets(stud->fio, FIO_SIZE, stdin);
    stud->fio[strlen(stud->fio)-1] = '\0';
 
    printf("Введите номер группы: ");     scanf("%d",&stud->nomer);  fflush(stdin);
    printf("Оценка по 1-му предмету: ");  scanf("%d",&stud->pred1);  fflush(stdin);
    printf("Оценка по 2-му предмету: ");  scanf("%d",&stud->pred2);  fflush(stdin);
    printf("Оценка по 3-му предмету: ");  scanf("%d",&stud->pred3);  fflush(stdin);
 
    stud->people = question("Участие в общественной работе(y-Да / n-Нет): ");
    
    return stud;
}
 
void create_file(const char filename[]){
    printf("\n******* Создание нового файла(%s) *******\n", filename);
    
    FILE *f = fopen(filename, "wb");
    if (!f){
        fprintf(stderr, "Невозможно создать файл: %s", filename);
        exit(EXIT_FAILURE);
    }
    
    do{
        Student stud;
        
        fwrite(input_stud(&stud), sizeof(Student), 1, f);
    }while (question("Продолжить( y-Да / n-Нет )?"));
    
    fclose(f);
    
    printf("\n******* Файл создан(%s) *******\n", filename);
}
 
void print_file(const char filename[]){
    printf("\n******* Просмотр файла(%s) *******\n", filename);
    
    FILE *f = fopen(filename, "rb");
    if (!f){
        fprintf(stderr, "Невозможно открыть файл: %s", filename);
        exit(EXIT_FAILURE);
    }
    
    printf("\n------------------------------------------------------------------\n");
    printf("|N  %-25s  %s  %s  %s  %s  %s\n", "FIO", "NOMER", "PRED1", "PRED2", "PRED3", "PEOPLE|");
    printf("------------------------------------------------------------------\n");
 
    Student stud;
    
    for (int i = 1; fread(&stud, sizeof(Student), 1, f); ++i){
        printf("|%d  %-25s  %5d  %5d  %5d  %5d  %6s|\n", i, stud.fio, stud.nomer,
                stud.pred1, stud.pred2, stud.pred3, (stud.people ? "true" : "false"));
    }
    
    
    printf("------------------------------------------------------------------\n");
    
    fclose(f);
}
 
void corect_file(const char filename[]){
    printf("\n******* Корректировка записей файла(%s) *******\n", filename);
    
    FILE *f = fopen(filename, "rb");
    if (!f){
        fprintf(stderr, "Невозможно открыть файл: %s", filename);
        exit(EXIT_FAILURE);
    }
    
    fseek(f, 0, SEEK_END);
    int number_studs = ftell(f) / sizeof(Student);
    rewind(f);
    
    Student *studs = (Student*)malloc(sizeof(Student) * number_studs);
    
    fread(studs, sizeof(Student), number_studs, f);
    
    fclose(f);
    
    switch (print_corect_menu()){
        case 1:  change_record(studs, number_studs);  break;
        case 2:  add_record(&studs, &number_studs);   break;
        case 3:  delete_record(studs, &number_studs); break; 
    }
 
    if (!(f = fopen(filename, "wb"))){
        fprintf(stderr, "Невозможно создать файл: %s", filename);
        exit(EXIT_FAILURE);
    }
    
    fwrite(studs, sizeof(Student), number_studs, f);
    
    fclose(f);
    
    free(studs);
    
    printf("\n******* Файла скорректирован(%s) *******\n", filename);
}
 
void doing(const char filename[]){
    const int BASE = 100; // базовая степендия
    
    printf("\n******* Выполнение задачи(%s) *******\n", filename);
    
    FILE *f = fopen(filename, "rb");
    if (!f){
        fprintf(stderr, "Невозможно открыть файл: %s", filename);
        exit(EXIT_FAILURE);
    }
    
    fseek(f, 0, SEEK_END);
    const int number_studs = ftell(f) / sizeof(Student);
    rewind(f);
    
    Student *studs = (Student*)malloc(sizeof(Student) * number_studs);
    
    fread(studs, sizeof(Student), number_studs, f);
    
    fclose(f);
    
    printf("\nВведите номер группы для расчета надбавки к стипендии: ");
    int nomer;
    scanf("%d", &nomer); fflush(stdin);
    
    Stipendia st[number_studs];
    
    int count_group = 0;
    
    for (int i = 0; i < number_studs; ++i){
        if (studs[i].nomer == nomer){
            strcpy(st[count_group].fio, studs[i].fio);
            
            if ((studs[i].pred1 == 5) && (studs[i].pred2 == 5) && (studs[i].pred3 == 5)){
                st[count_group].n = BASE + (BASE / 100 * (studs[i].people ? 50 : 25));
            }else if ((studs[i].pred1 > 3) && (studs[i].pred2 > 3) && (studs[i].pred3 > 3)){
                st[count_group].n = BASE + (BASE / 100 * 10);
            }else if (!((studs[i].pred1 < 3) && (studs[i].pred2 < 3) && (studs[i].pred3 < 3)) && studs[i].people){
                int count_three = 0;
                
                if (studs[i].pred1 == 3) ++count_three;
                if (studs[i].pred2 == 3) ++count_three;
                if (studs[i].pred3 == 3) ++count_three;
                
                if (count_three == 1)  st[i].n = BASE + (BASE / 100 * 10);
            }else{
                st[count_group].n = BASE;
            }
            
            ++count_group;
        }
    }
    if (count_group > 1)  qsort(st, count_group, sizeof(Stipendia), compare);
    
    printf("\nРезультат\n");
    printf("--------------------------------------\n");
    printf("|%-25s  %s\n", "FIO", "STIPENDIA|");
    printf("--------------------------------------\n");
    
    for (int i = 0; i < count_group; ++i){
        printf("|%-25s  %9d|\n", st[i].fio, st[i].n);
    }
    
    printf("--------------------------------------\n");
}
 
 
int print_corect_menu(void){
    printf("\n\t\t\tДЕЙСТВИЯ\n");
    printf("\t\t1 - Изменить запись\n");
    printf("\t\t2 – Добавить запись\n");
    printf("\t\t3 – Удалить запись\n");
    printf("Выберите  действие: ");
    
    int n;
    scanf("%d",&n);
    fflush(stdin);
    
    return n;
}
 
void change_record(Student *studs, const int number_studs){
    printf("\nВведите FIO для изменения: ");
    
    char fio[FIO_SIZE];
    fgets(fio, FIO_SIZE, stdin);
    fio[strlen(fio)-1] = '\0';
    
    int i = 0;
    for (; i < number_studs; ++i){
        if (!strcmp(studs[i].fio, fio))  break;
    }
    
    if (i != number_studs){
        printf("\nНайдено:   %s  %d  %d  %d  %d  %s\n", studs[i].fio, studs[i].nomer, studs[i].pred1,
                studs[i].pred2, studs[i].pred3, (studs[i].people ? "true" : "false"));
                
        printf("Введите данные для замены\n");
        
        input_stud(&studs[i]);
    }else{
        printf("\nFAIL: FIO такое как '%s' не найдено\n", fio);
    }
}
 
void add_record(Student **studs, int *number_studs){
    printf("\nВведите данные для добавления\n");
    
    Student stud;
    
    input_stud(&stud);
    
    Student *new_studs = (Student*)malloc(sizeof(Student) * (*number_studs + 1));
    
    memcpy(new_studs, *studs, sizeof(Student) * *number_studs);
    
    new_studs[(*number_studs)++] = stud;
    
    free(*studs);
 
    *studs = new_studs;
    
    printf("\nДобавлено:   %s  %d  %d  %d  %d  %s\n", stud.fio, stud.nomer, stud.pred1,
                stud.pred2, stud.pred3, (stud.people ? "true" : "false"));
}
 
void delete_record(Student *studs, int *number_studs){
    printf("\nВведите FIO для удаления: ");
    
    char fio[FIO_SIZE];
    fgets(fio, FIO_SIZE, stdin);
    fio[strlen(fio)-1] = '\0';
    
    int i = 0;
    for (; i < *number_studs; ++i){
        if (!(strcmp(studs[i].fio, fio)))  break;
    }
    
    if (i != *number_studs){
        printf("\nУдалено:   %s  %d  %d  %d  %d  %s\n", studs[i].fio, studs[i].nomer, studs[i].pred1,
                studs[i].pred2, studs[i].pred3, (studs[i].people ? "true" : "false"));
        
        for (int j = i; j < *number_studs-1; ++j)  studs[j] = studs[j+1];
        
        --*number_studs;
    }else{
        printf("\nFAIL: FIO такое как '%s' не найдено\n", fio);
    }
}
 
bool question(const char str[]){
    char ch;
    
    for (;;){
        printf("%s", str);
        
        ch = tolower(getchar());
        fflush(stdin);
        
        if (strchr("yn", ch))  break;
        
        printf("Неверное значение, повторите.\t");
    }
    
    return ch == 'y';
}
 
int compare(const void *arg1, const void *arg2){
    return strcmp(((Stipendia*)arg1)->fio, ((Stipendia*)arg2)->fio);
}

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


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

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

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