Сформировать массив структур из уже созданных - 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); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д