#include // cin, cout #include // ifstream, ofstream const int LINE_BUFFER_SIZE = 1024; const int MAX_STUDENT_PROP_SIZE = 2048; bool strNotEqual(const char* a, const char* b) { for (int i = 0; a[i] != '\0' || b[i] != '\0'; i++) if (a[i] != b[i]) return true; return false; } /* Student */ struct Student { char FirstName[MAX_STUDENT_PROP_SIZE]; char LastName[MAX_STUDENT_PROP_SIZE]; char Email[MAX_STUDENT_PROP_SIZE]; char FN[MAX_STUDENT_PROP_SIZE]; }; void printStudent(Student st) { std::cout << "Name = " << st.FirstName << " " << st.LastName << ", Email: " << st.Email << ", FN: " << st.FN << std::endl; } Student parseStudent(const char* str) { Student toRet = {}; char* prop = toRet.FirstName; for (int i = 0, j = 0; str[i] != '\0'; i++) { if (str[i] == ',') { if (prop == toRet.FirstName) prop = toRet.LastName; else if (prop == toRet.LastName) prop = toRet.Email; else if (prop == toRet.Email) prop = toRet.FN; j = 0; } else prop[j++] = str[i]; } return toRet; } /* StudentsList */ struct StudentsList { Student* students; int count; int length; }; bool resizeStudentsList(StudentsList& sl, int newSize) { if (newSize < sl.count) return false; // We cant fit all of the old students in the new students array Student* temp = new Student[newSize]; for (int i = 0; i < sl.count; i++) temp[i] = sl.students[i]; delete[] sl.students; sl.students = temp; return true; } void addStudents(StudentsList& sl, Student st) { if (sl.count == sl.length) { sl.length = (!sl.length) ? 2 : sl.length << 1; resizeStudentsList(sl, sl.length); } sl.students[sl.count++] = st; } int findStudentIndByFN(const StudentsList& sl, const char* FN) { for (int i = 0; i < sl.count; i++) if (strNotEqual(sl.students[i].FN, FN)) return i; std::cout << "Error: No student with FN of " << FN << "!" << std::endl; return -1; } StudentsList getStudentsListFromFile(const char* fileName) { std::ifstream inFile(fileName); if (!inFile.is_open()) { std::cout << "Error: Could not open file!" << std::endl; return {}; } StudentsList sl = {}; char buffer[LINE_BUFFER_SIZE]; while (!inFile.eof()) { inFile.getline(buffer, LINE_BUFFER_SIZE); if (buffer[0] != '\0') addStudents(sl, parseStudent(buffer)); } return sl; } /* Commands */ bool isCommand(const char* inputBuffer, const char* command) { // The buffer could get dirty with leftover data, so we check only if the beginning matches for (int i = 0; command[i] != '\0'; i++) if (inputBuffer[i] != command[i]) return false; return true; } void printStudentByFN(const StudentsList& sl, const char* FN) { int stInd = findStudentIndByFN(sl, FN); if (stInd >= 0) printStudent(sl.students[stInd]); } void replaceStudentEmail(const StudentsList& sl, const char* FN, const char* newEmail) { int stdInd = findStudentIndByFN(sl, FN); if (stdInd < 0) return; Student& st = sl.students[stdInd]; for (int i = 0; st.Email[i] != '\0' || newEmail[i] != '\0'; i++) st.Email[i] = (newEmail[i] == '\0') ? '\0' : newEmail[i]; } void saveToFile(const StudentsList& sl, const char* newFileName) { std::ofstream newFile(newFileName); if (!newFile.is_open()) { std::cout << "Error: File could not be opened!" << std::endl; return; } for (int i = 0; i < sl.count; i++) { Student st = sl.students[i]; newFile << st.FirstName << "," << st.LastName << "," << st.Email << "," << st.FN << std::endl; } newFile.close(); } /* Main */ int main() { char inputBuffer[LINE_BUFFER_SIZE]; std::cout << "Open file:" << std::endl << ">"; std::cin >> inputBuffer; StudentsList readSL = getStudentsListFromFile(inputBuffer); if (readSL.students == nullptr) return -1; do { std::cout << ">"; std::cin >> inputBuffer; if (isCommand(inputBuffer, "print")) { std::cin >> inputBuffer; printStudentByFN(readSL, inputBuffer); } else if (isCommand(inputBuffer, "edit")) { char tempFNBuffer[LINE_BUFFER_SIZE]; std::cin >> tempFNBuffer >> inputBuffer; replaceStudentEmail(readSL, tempFNBuffer, inputBuffer); } else if (isCommand(inputBuffer, "save")) { std::cin >> inputBuffer; saveToFile(readSL, inputBuffer); } } while (!isCommand(inputBuffer, "end")); delete[] readSL.students; }