This is a sample that will be written together in programming 2 in the class dedicated to structures.
Data file format isĀ <name> <grade> , where the name can consist from up to 63 characters and be a single word. Grade must be an integer. Data fields are separated by spaces.
Notice, that there is no guards for buffer overflow – if you enter 64 or more characters for the name, it will write beyond the bounds of the array and can cause data corruption or the program crashing.
1 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 |
#include <stdio.h> #include <stdlib.h> /* 1 to enable printing debug statements, 0 to silence them */ #define DEBUG 0 /* Predefined array limits */ #define STR_MAX_LEN 64 #define STUDENT_MAX_CNT 32 /* Options for command line args */ #define ARGS_CNT 2 #define ARGS_EXEC_NAME argv[0] #define ARGS_FILE_NAME argv[1] typedef struct { char name[STR_MAX_LEN]; int grade; } student; int ReadData(char *fName, student *students, int readingLimit); void PrintData(student *students, int cnt); int main(int argc, char **argv) { /* Check that argument was passed*/ if (argc != ARGS_CNT) { fprintf(stderr, "Usage: %s data_file\n", ARGS_EXEC_NAME); return EXIT_FAILURE; } /* Create struct array */ student studentGrades[STUDENT_MAX_CNT]; /* Read student data from file */ int studentCnt = ReadData(ARGS_FILE_NAME, studentGrades, STUDENT_MAX_CNT); /* Print student data */ PrintData(studentGrades, studentCnt); return EXIT_SUCCESS; } /** * Description: Reads student data from a file into a struct array * * Parameters: fName - name of the file for input data * students - struct array to store the data * readingLimit - maximum entries to read (struct array length) * * Return: Number of studens read from the file */ int ReadData(char *fName, student *students, int readingLimit) { FILE *fStudents = fopen(fName, "r"); if (fStudents == NULL) { fprintf(stderr, "Error opening input file '%s'!\n", fName); perror(""); /* Returns 0 students read from the file, allows program to continue */ return 0; /* Alternative: kill the program */ // exit(EXIT_FAILURE); } /* Counter for number of students from file */ int cnt = 0; while (fscanf(fStudents, "%s %d", students[cnt].name, &students[cnt].grade) == 2) { /* Debugging print to check if input was read successfully */ if (DEBUG) printf("DBG: from file (%d): %s %d\n", cnt + 1, students[cnt].name, students[cnt].grade); /* Student successfully read, increment student count */ cnt++; /* Avoid overflowing the array */ if (cnt >= readingLimit) { fprintf(stderr, "ERROR: File is too long! Allowed max is %d!\n" "Reading of the file has been stopped, continuing " "with a partial dataset!\n", readingLimit); break; } } /* Close the input file */ fclose(fStudents); if (DEBUG) printf("Reading finished, got %d entries\n", cnt); /* Returns number of students read */ return cnt; } void PrintData(student *students, int cnt) { /* Handling of no students */ if (cnt == 0) { fprintf(stderr, "Student db is empty!\n"); return; } printf("Student list contains %d students:\n", cnt); for (int i = 0; i < cnt; i++) { printf("%s %d\n", students[i].name, students[i].grade); } } |