Мне нужно чтобы все записывалось в бинарный файл (предусмотреть, если его нет, и тогда сказать что база данных пуста). Тоесть, чтобы при первом запуске бд была пустая, человек заполнил структуру, она сохранилась в бинарный файл и при следуюзем запуске, когда человек захочет посмотреть список студентов он увидит данные о том студенте, данные о котором вводил в прошлый раз. Не пойму то-ли я как-то неправильно считываю, то-ли сохраняю в файл что-то не то. Помогите умоляю!:с #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> int isValidPositiveNaturalNumber2(const char* str) { // Check int r = 0; while (str[r] != '\0') { if (!isdigit(str[r]) || isalpha(str[r])) { return 0; } r++; } return 1; } typedef enum { // Enum MALE, FEMALE } Gender; typedef struct { // Struct int year; int month; int day; } Date; typedef struct Student { // Struct char *lastName; char *firstName; char *middleName; Date birthDate; char *group; Gender gender; struct Student* next; } Student; void freeStudentList(Student *students) { // Free list of students Student *current = students; while (current != NULL) { Student *temp = current; current = current->next; free(temp->lastName); free(temp->firstName); free(temp->middleName); free(temp->group); free(temp); } } void appendStudent(Student **head, Student *newStudent) { // Append student to the end of the list if (*head == NULL) { *head = newStudent; } else { Student *current = *head; while (current->next != NULL) { current = current->next; } current->next = newStudent; } } Student* createStudentNode(const char *lastName, const char *firstName, const char *middleName, Date birthDate, const char *group, Gender gender) { // Create a new student node Student *newStudent = (Student*)malloc(sizeof(Student)); if (newStudent == NULL) { printf("Error: Failed to allocate memory for a new student\n"); return NULL; } newStudent->lastName = strdup(lastName); newStudent->firstName = strdup(firstName); newStudent->middleName = strdup(middleName); newStudent->birthDate = birthDate; newStudent->group = strdup(group); newStudent->gender = gender; newStudent->next = NULL; return newStudent; } void printStudentList(Student *students) { // Print the list of students FILE *file = fopen("data.bin", "rb"); // Open file for reading in binary mode if (file == NULL) { printf("The list of students is empty.\n"); return; } // Read data from the file Student *current = (Student*)malloc(sizeof(Student)); if (current == NULL) { printf("Error: Failed to allocate memory for a student.\n"); fclose(file); return; } size_t read = fread(current, sizeof(Student), 1, file); if (read != 1) { printf("The list of students is empty.\n"); fclose(file); free(current); return; } printf("List of students:\n"); while (!feof(file)) { printf("%s %s %s\n", current->lastName, current->firstName, current->group); read = fread(current, sizeof(Student), 1, file); } fclose(file); free(current); } void appendNewStudent(Student **head) { // Append a new student char lastName[50]; char firstName[50]; char middleName[50]; char yearStr[20], monthStr[20], dayStr[20], genderChoiceStr[20]; int year, month, day, genderChoice; char group[10]; printf("Enter the student's last name: "); scanf("%s", lastName); printf("Enter the student's first name: "); scanf("%s", firstName); printf("Enter the student's middle name: "); scanf("%s", middleName); while (1) { printf("Enter the student's birth year: "); year = scanf("%s", yearStr); if (year != 1 || !isValidPositiveNaturalNumber2(yearStr)) { printf("Invalid input. Please enter a positive integer.\n"); while (getchar() != '\n'); continue; } year = atoi(yearStr); if (year < 1900 || year > 2024) { printf("The birth year should be between 1900 and 2024. Please try again.\n"); } else { break; } } // Similar loops for month and day inputs printf("Enter the student's group: "); scanf("%s", group); // Similar loop for gender input Gender gender = genderChoice == 0 ? MALE : FEMALE; Date birthDate = {year, month, day}; Student *newStudent = createStudentNode(lastName, firstName, middleName, birthDate, group, gender); if (newStudent == NULL) { printf("Error: Failed to add a new student.\n"); return; } appendStudent(head, newStudent); // Get data from the file FILE *file = fopen("data.bin", "ab"); // Open file for appending in binary mode if (file == NULL) { printf("Error: Failed to open the file for writing.\n"); return; } // Write data of the new student to the file size_t written = fwrite(newStudent, sizeof(Student), 1, file); if (written != 1) { printf("Error writing to the file.\n"); } else { printf("The student has been successfully added to the list and written to the file.\n"); } fclose(file); } void menu(Student *students) { // Main menu char userChoiceStr[20]; int result; while (1) { result = scanf("%s", userChoiceStr); if (result != 1 || !isValidPositiveNaturalNumber2(userChoiceStr)) { printf("Invalid input. Please enter a positive integer.\n"); while (getchar() != '\n'); continue; } result = atoi(userChoiceStr); if (result == 4) { break; } switch (result) { case 1: printStudentList(students); break; case 2: appendNewStudent(&students); break; case 3: printf("sdfsd"); break; default: printf("Invalid choice, please select again.\n"); break; } } } int main() { Student* students = NULL; // Initialization menu(students); freeStudentList(students); // Cleanup return 0; } C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> int isValidPositiveNaturalNumber2(const char* str) { // Check int r = 0; while (str[r] != '\0') { if (!isdigit(str[r]) || isalpha(str[r])) { return 0; } r++; } return 1; } typedef enum { // Enum MALE, FEMALE } Gender; typedef struct { // Struct int year; int month; int day; } Date; typedef struct Student { // Struct char *lastName; char *firstName; char *middleName; Date birthDate; char *group; Gender gender; struct Student* next; } Student; void freeStudentList(Student *students) { // Free list of students Student *current = students; while (current != NULL) { Student *temp = current; current = current->next; free(temp->lastName); free(temp->firstName); free(temp->middleName); free(temp->group); free(temp); } } void appendStudent(Student **head, Student *newStudent) { // Append student to the end of the list if (*head == NULL) { *head = newStudent; } else { Student *current = *head; while (current->next != NULL) { current = current->next; } current->next = newStudent; } } Student* createStudentNode(const char *lastName, const char *firstName, const char *middleName, Date birthDate, const char *group, Gender gender) { // Create a new student node Student *newStudent = (Student*)malloc(sizeof(Student)); if (newStudent == NULL) { printf("Error: Failed to allocate memory for a new student\n"); return NULL; } newStudent->lastName = strdup(lastName); newStudent->firstName = strdup(firstName); newStudent->middleName = strdup(middleName); newStudent->birthDate = birthDate; newStudent->group = strdup(group); newStudent->gender = gender; newStudent->next = NULL; return newStudent; } void printStudentList(Student *students) { // Print the list of students FILE *file = fopen("data.bin", "rb"); // Open file for reading in binary mode if (file == NULL) { printf("The list of students is empty.\n"); return; } // Read data from the file Student *current = (Student*)malloc(sizeof(Student)); if (current == NULL) { printf("Error: Failed to allocate memory for a student.\n"); fclose(file); return; } size_t read = fread(current, sizeof(Student), 1, file); if (read != 1) { printf("The list of students is empty.\n"); fclose(file); free(current); return; } printf("List of students:\n"); while (!feof(file)) { printf("%s %s %s\n", current->lastName, current->firstName, current->group); read = fread(current, sizeof(Student), 1, file); } fclose(file); free(current); } void appendNewStudent(Student **head) { // Append a new student char lastName[50]; char firstName[50]; char middleName[50]; char yearStr[20], monthStr[20], dayStr[20], genderChoiceStr[20]; int year, month, day, genderChoice; char group[10]; printf("Enter the student's last name: "); scanf("%s", lastName); printf("Enter the student's first name: "); scanf("%s", firstName); printf("Enter the student's middle name: "); scanf("%s", middleName); while (1) { printf("Enter the student's birth year: "); year = scanf("%s", yearStr); if (year != 1 || !isValidPositiveNaturalNumber2(yearStr)) { printf("Invalid input. Please enter a positive integer.\n"); while (getchar() != '\n'); continue; } year = atoi(yearStr); if (year < 1900 || year > 2024) { printf("The birth year should be between 1900 and 2024. Please try again.\n"); } else { break; } } // Similar loops for month and day inputs printf("Enter the student's group: "); scanf("%s", group); // Similar loop for gender input Gender gender = genderChoice == 0 ? MALE : FEMALE; Date birthDate = {year, month, day}; Student *newStudent = createStudentNode(lastName, firstName, middleName, birthDate, group, gender); if (newStudent == NULL) { printf("Error: Failed to add a new student.\n"); return; } appendStudent(head, newStudent); // Get data from the file FILE *file = fopen("data.bin", "ab"); // Open file for appending in binary mode if (file == NULL) { printf("Error: Failed to open the file for writing.\n"); return; } // Write data of the new student to the file size_t written = fwrite(newStudent, sizeof(Student), 1, file); if (written != 1) { printf("Error writing to the file.\n"); } else { printf("The student has been successfully added to the list and written to the file.\n"); } fclose(file); } void menu(Student *students) { // Main menu char userChoiceStr[20]; int result; while (1) { result = scanf("%s", userChoiceStr); if (result != 1 || !isValidPositiveNaturalNumber2(userChoiceStr)) { printf("Invalid input. Please enter a positive integer.\n"); while (getchar() != '\n'); continue; } result = atoi(userChoiceStr); if (result == 4) { break; } switch (result) { case 1: printStudentList(students); break; case 2: appendNewStudent(&students); break; case 3: printf("sdfsd"); break; default: printf("Invalid choice, please select again.\n"); break; } } } int main() { Student* students = NULL; // Initialization menu(students); freeStudentList(students); // Cleanup return 0; }
Сам я хз, но вот что нейронка написала: Проблема возникает из-за того, что вы пытаетесь записывать и читать структуру Student непосредственно в бинарный файл, что не является надежным подходом из-за различий в выравнивании памяти и других факторов, что может привести к непредсказуемым результатам. Более надежным и распространенным методом является сериализация структур данных перед записью и их десериализация после чтения из файла. Давайте изменим ваш код для использования этого подхода. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef enum { MALE, FEMALE } Gender; typedef struct { int year; int month; int day; } Date; typedef struct { char lastName[50]; char firstName[50]; char middleName[50]; Date birthDate; char group[10]; Gender gender; } Student; void printStudentList() { FILE *file = fopen("data.bin", "rb"); if (file == NULL) { printf("The list of students is empty.\n"); return; } Student current; printf("List of students:\n"); while (fread(¤t, sizeof(Student), 1, file)) { printf("%s %s %s\n", current.lastName, current.firstName, current.group); } fclose(file); } void appendNewStudent() { Student newStudent; printf("Enter the student's last name: "); scanf("%s", newStudent.lastName); printf("Enter the student's first name: "); scanf("%s", newStudent.firstName); printf("Enter the student's middle name: "); scanf("%s", newStudent.middleName); printf("Enter the student's birth year: "); scanf("%d", &newStudent.birthDate.year); printf("Enter the student's birth month: "); scanf("%d", &newStudent.birthDate.month); printf("Enter the student's birth day: "); scanf("%d", &newStudent.birthDate.day); printf("Enter the student's group: "); scanf("%s", newStudent.group); char genderChoice; do { printf("Enter the student's gender (M/F): "); scanf(" %c", &genderChoice); genderChoice = toupper(genderChoice); } while (genderChoice != 'M' && genderChoice != 'F'); newStudent.gender = (genderChoice == 'M') ? MALE : FEMALE; FILE *file = fopen("data.bin", "ab"); if (file == NULL) { printf("Error: Failed to open the file for writing.\n"); return; } fwrite(&newStudent, sizeof(Student), 1, file); fclose(file); printf("The student has been successfully added to the list and written to the file.\n"); } int main() { while (1) { printf("1. Print student list\n"); printf("2. Add new student\n"); printf("3. Exit\n"); int choice; scanf("%d", &choice); switch (choice) { case 1: printStudentList(); break; case 2: appendNewStudent(); break; case 3: return 0; default: printf("Invalid choice\n"); } } }
Вроде как это должно фиксануть если я правильно проблему понял void writeStringToFile(FILE *file, const char *str) { size_t len = strlen(str) + 1; fwrite(&len, sizeof(len), 1, file); fwrite(str, sizeof(char), len, file); } char* readStringFromFile(FILE *file) { size_t len; if (fread(&len, sizeof(len), 1, file) != 1) { return NULL; } char *str = malloc(sizeof(char) * len); if (fread(str, sizeof(char), len, file) != len) { free(str); return NULL; } return str; } void appendNewStudent(Student **head) { // ... твой код ... FILE *file = fopen("data.bin", "ab"); if (file == NULL) { printf("Error: Failed to open the file for writing.\n"); return; } fwrite(newStudent, sizeof(Student), 1, file); writeStringToFile(file, newStudent->lastName); writeStringToFile(file, newStudent->firstName); writeStringToFile(file, newStudent->middleName); writeStringToFile(file, newStudent->group); // ... твой код ... } void printStudentList(Student *students) { FILE *file = fopen("data.bin", "rb"); if (file == NULL) { printf("The list of students is empty.\n"); return; } Student *current = (Student*)malloc(sizeof(Student)); if (current == NULL) { printf("Error: Failed to allocate memory for a student.\n"); fclose(file); return; } while (fread(current, sizeof(Student), 1, file) == 1) { current->lastName = readStringFromFile(file); current->firstName = readStringFromFile(file); current->middleName = readStringFromFile(file); current->group = readStringFromFile(file); printf("%s %s %s\n", current->lastName, current->firstName, current->group); free(current->lastName); free(current->firstName); free(current->middleName); free(current->group); } fclose(file); free(current); } C void writeStringToFile(FILE *file, const char *str) { size_t len = strlen(str) + 1; fwrite(&len, sizeof(len), 1, file); fwrite(str, sizeof(char), len, file); } char* readStringFromFile(FILE *file) { size_t len; if (fread(&len, sizeof(len), 1, file) != 1) { return NULL; } char *str = malloc(sizeof(char) * len); if (fread(str, sizeof(char), len, file) != len) { free(str); return NULL; } return str; } void appendNewStudent(Student **head) { // ... твой код ... FILE *file = fopen("data.bin", "ab"); if (file == NULL) { printf("Error: Failed to open the file for writing.\n"); return; } fwrite(newStudent, sizeof(Student), 1, file); writeStringToFile(file, newStudent->lastName); writeStringToFile(file, newStudent->firstName); writeStringToFile(file, newStudent->middleName); writeStringToFile(file, newStudent->group); // ... твой код ... } void printStudentList(Student *students) { FILE *file = fopen("data.bin", "rb"); if (file == NULL) { printf("The list of students is empty.\n"); return; } Student *current = (Student*)malloc(sizeof(Student)); if (current == NULL) { printf("Error: Failed to allocate memory for a student.\n"); fclose(file); return; } while (fread(current, sizeof(Student), 1, file) == 1) { current->lastName = readStringFromFile(file); current->firstName = readStringFromFile(file); current->middleName = readStringFromFile(file); current->group = readStringFromFile(file); printf("%s %s %s\n", current->lastName, current->firstName, current->group); free(current->lastName); free(current->firstName); free(current->middleName); free(current->group); } fclose(file); free(current); }