patterncMinor
Calculate the average score of groups and each student, C
Viewed 0 times
groupstheeachstudentaveragescorecalculateand
Problem
I have a file containing information about the session of students. The structure of this file is: group number, student name, exams, and tests.
So, this is my program and maybe I can make something better?
```
#include
#include
#include
#include
#include
#define N 50
void debt();
void student_score();
void group_score();
struct STUDENTS {
int group;
char name[100];
char test[15];
int exam;
};
struct STUDENTS student_list[N];
int main() {
FILE *file;
int choice;
char buffer[200];
int i = 0;
file = fopen("students.txt", "r");
if (file == NULL) {
puts("students.txt не найден");
return 1;
}
while (fgets(buffer, sizeof buffer, file) != NULL) {
sscanf(strdup(buffer), "%d %[^0-9] %d %s", &student_list[i].group, student_list[i].name, &student_list[i].exam, student_list[i].test);
i++;
}
fclose(file);
int student_list_size = i;
do {
puts("\nВыберите номер пункта меню:");
puts("1 - Cтуденты, имеющие задолженности");
puts("2 – Средний балл каждого студента");
puts("3 – Средний балл всей группы");
puts("4 - Выход\n");
scanf("%d", &choice);
switch (choice) {
case 1:
debt(student_list_size);
break;
case 2:
student_score(student_list_size);
break;
case 3:
group_score(student_list_size);
break;
case 4:
break;
default:
puts("\nНужно вводить номер пункта от 1 до 4");
break;
}
} while (choice != 4);
return 0;
}
void debt(int student_list_size) {
int counter_debt;
wchar_t test_wchar[15];
wchar_t * pch;
setlocale(LC_ALL, "");
for (int i = 0; i 0) {
printf("%d %s: %d\n", student_list[i].group, student_list[i].name, counter_debt);
}
}
}
void student_score(int student_
debt()function find and print the names of underachieving students.
student_score()calculate the average score of groups
group_score()calculate the average score of each student.
So, this is my program and maybe I can make something better?
```
#include
#include
#include
#include
#include
#define N 50
void debt();
void student_score();
void group_score();
struct STUDENTS {
int group;
char name[100];
char test[15];
int exam;
};
struct STUDENTS student_list[N];
int main() {
FILE *file;
int choice;
char buffer[200];
int i = 0;
file = fopen("students.txt", "r");
if (file == NULL) {
puts("students.txt не найден");
return 1;
}
while (fgets(buffer, sizeof buffer, file) != NULL) {
sscanf(strdup(buffer), "%d %[^0-9] %d %s", &student_list[i].group, student_list[i].name, &student_list[i].exam, student_list[i].test);
i++;
}
fclose(file);
int student_list_size = i;
do {
puts("\nВыберите номер пункта меню:");
puts("1 - Cтуденты, имеющие задолженности");
puts("2 – Средний балл каждого студента");
puts("3 – Средний балл всей группы");
puts("4 - Выход\n");
scanf("%d", &choice);
switch (choice) {
case 1:
debt(student_list_size);
break;
case 2:
student_score(student_list_size);
break;
case 3:
group_score(student_list_size);
break;
case 4:
break;
default:
puts("\nНужно вводить номер пункта от 1 до 4");
break;
}
} while (choice != 4);
return 0;
}
void debt(int student_list_size) {
int counter_debt;
wchar_t test_wchar[15];
wchar_t * pch;
setlocale(LC_ALL, "");
for (int i = 0; i 0) {
printf("%d %s: %d\n", student_list[i].group, student_list[i].name, counter_debt);
}
}
}
void student_score(int student_
Solution
-
Completely prototype functions:
-
Avoid naked magic numbers. Use #define or a constant to self document various numbers.
-
Use
-
Localize variables. This approaches a style issue, but declaring variables close to their use has value.
-
The
-
The return value of
-
Use valid
-
Conversions
-
The extra
Completely prototype functions:
debt() student_score() group_score();// void debt();
void debt(int student_list_size);-
Avoid naked magic numbers. Use #define or a constant to self document various numbers.
#define TEST_N (15)
struct STUDENTS {
...
char test[TEST_N];
};
void debt(int student_list_size) {
// wchar_t test_wchar[15];
wchar_t test_wchar[TEST_N];
...
// mbstowcs(test_wchar, student_list[i].test, 15);
mbstowcs(test_wchar, student_list[i].test, TEST_N);-
Use
size_t for array index types and the result of sizeof. int may not be the right size to use as an index. (Also i in main())// void student_score(int student_list_size) {
void student_score(size_t student_list_size) {
...
// for (int i = 0; i < student_list_size; i++) {
for (size_t i = 0; i < student_list_size; i++) {-
Localize variables. This approaches a style issue, but declaring variables close to their use has value.
void student_score(int student_list_size) {
// int exam;
// int average;
// int digit;
// int counter_digits;
for (int i = 0; i < student_list_size; i++) {
int exam;
int average;
int digit;
int counter_digits;-
The
strdup() serves no purpose. Eliminate it.// sscanf(strdup(buffer), "%d ...
sscanf(buffer, "%d ...-
The return value of
sscanf() should be checked and string widths limited. Note: student_list[i].name will have a ' ' at the end.// sscanf(buffer, "%d %[^0-9] %d %s", &student_list[i].group, ...
if (4 != sscanf(buffer, "%d %99[^0-9] %d %14s", &student_list[i].group, ...) {
Handle_Format_Error();-
Use valid
main() signature.int main() {
int main(void) {-
Conversions
char to/from wchar_t may need different sizes.-
The extra
'\n' in puts("4 - Выход\n"); looks wrong. Guess I am not a fan of puts(). Why not use 1 function call?fputs("\nВыберите номер пункта меню:\n"
"1 - Cтуденты, имеющие задолженности\n"
"2 – Средний балл каждого студента\n"
"3 – Средний балл всей группы\n"
"4 - Выход\n"
"\n", stdout);Code Snippets
// void debt();
void debt(int student_list_size);#define TEST_N (15)
struct STUDENTS {
...
char test[TEST_N];
};
void debt(int student_list_size) {
// wchar_t test_wchar[15];
wchar_t test_wchar[TEST_N];
...
// mbstowcs(test_wchar, student_list[i].test, 15);
mbstowcs(test_wchar, student_list[i].test, TEST_N);// void student_score(int student_list_size) {
void student_score(size_t student_list_size) {
...
// for (int i = 0; i < student_list_size; i++) {
for (size_t i = 0; i < student_list_size; i++) {void student_score(int student_list_size) {
// int exam;
// int average;
// int digit;
// int counter_digits;
for (int i = 0; i < student_list_size; i++) {
int exam;
int average;
int digit;
int counter_digits;// sscanf(strdup(buffer), "%d ...
sscanf(buffer, "%d ...Context
StackExchange Code Review Q#75044, answer score: 3
Revisions (0)
No revisions yet.