HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Calculate the average score of groups and each student, C

Submitted by: @import:stackexchange-codereview··
0
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.

  • 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: 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.