C
C
CodeInside2016-09-02 17:50:03
C++ / C#
CodeInside, 2016-09-02 17:50:03

Why do the values ​​of the structure object fields change?

The program receives the username and password. The getStudentData function looks for a student in the file by the specified login and reads his data. Returns a pointer to the completed object if the student is found and nullptr if the student is not found. And this is the essence of the question: when you first access the structure fields (through a pointer), everything is fine, but when you re-apply, some kind of garbage is displayed and "There is no access to read at the address ..." The fact is that between these calls there are no manipulation does not take place. What is the problem?
This is how I write the data to the database.

FILE * accounts_w = nullptr;
  fopen_s(&accounts_w, "Accounts.dat", "wb");
  
  char * str = "Anto_cn69";
  short size = strlen(str);
  fwrite(&size, sizeof(size), 1, accounts_w);
  fputs(str, accounts_w);

  str = "4utc1";
  size = strlen(str);
  fwrite(&size, sizeof(size), 1, accounts_w);
  fputs(str, accounts_w);

  str = "Antonyuk";
  size = strlen(str);
  fwrite(&size, sizeof(size), 1, accounts_w);
  fputs(str, accounts_w);

  str = "Arkadiy";
  size = strlen(str);
  fwrite(&size, sizeof(size), 1, accounts_w);
  fputs(str, accounts_w);

  str = "Olegovich";
  size = strlen(str);
  fwrite(&size, sizeof(size), 1, accounts_w);
  fputs(str, accounts_w);

  int age = 18;
  fwrite(&age, sizeof(age), 1, accounts_w);

  str = "ECE-1511";
  fputs(str, accounts_w);

  str = "Programming";
  size = strlen(str);
  fwrite(&size, sizeof(size), 1, accounts_w);
  fputs(str, accounts_w);

  _getch();

  fclose(accounts_w);
  delete[] str;

Student * getStudentData(FILE * accounts, char * login)
{
  Student student;
  student.login = new char[strlen(login) + 1];
  //size+1 для '\0'
  student.password = new char[MAX_PASSWORD_SIZE + 1];
  student.surname = new char[MAX_SURNAME_SIZE + 1];
  student.name = new char[MAX_NAME_SIZE + 1];
  student.patronymic = new char[MAX_PATRONYMIC_SIZE + 1];
  student.group = new char[GROUP_NAME_SIZE + 1];
  student.faculty = new char[MAX_FACULTY_SIZE + 1];

  char * temp_login = new char[MAX_LOGIN_SIZE + 1];// Получает значения логинов при считывании информации с файла
  short log_s, pass_s, surn_s, name_s, patr_s, faculty_s;//_s - "size"

  if (!CheckStructFields(student))
  {
    showMessage("Error! Not allocate memory for structure fields.");
  };

  while (std::fread(&log_s, sizeof(log_s), 1, accounts) > 0 && std::fread(temp_login, sizeof(char), log_s, accounts) > 0)
  {
    temp_login[log_s] = '\0';

    //не помню что хотел здесь написать

    if (strcmp(temp_login, login) == 0)//если введённый пользователем логин найден в "БД"
    {
      //Считывание и запись информации о студенте

      // Логин
      strcpy(student.login, login);

      // Пароль
      fread(&pass_s, sizeof(pass_s), 1, accounts);
      fread(student.password, sizeof(char), pass_s, accounts);
      student.password[pass_s] = '\0';

      // Фамилия
      fread(&surn_s, sizeof(surn_s), 1, accounts);
      fread(student.surname, sizeof(char), surn_s, accounts);
      student.surname[surn_s] = '\0';

      // Имя
      fread(&name_s, sizeof(name_s), 1, accounts);
      fread(student.name, sizeof(char), name_s, accounts);
      student.name[name_s] = '\0';

      // Отчество
      fread(&patr_s, sizeof(patr_s), 1, accounts);
      fread(student.patronymic, sizeof(char), patr_s, accounts);
      student.patronymic[patr_s] = '\0';

      // Возраст
      int age;
      fread(&age, sizeof(age), 1, accounts);
      student.age = age;

      // Группа
      fread(student.group, sizeof(char), GROUP_NAME_SIZE, accounts);
      student.group[GROUP_NAME_SIZE] = '\0';

      // Факультет
      fread(&faculty_s, sizeof(faculty_s), 1, accounts);
      fread(student.faculty, sizeof(char), faculty_s, accounts);
      student.faculty[faculty_s] = '\0';

      return &student;
    }
    else//если логины не совпадают
    {
      //"перепрыгивание" ненужной информации
      //пароль
      fread(&pass_s, sizeof(pass_s), 1, accounts);
      fseek(accounts, pass_s, SEEK_CUR);

      //фамилия
      fread(&surn_s, sizeof(surn_s), 1, accounts);
      fseek(accounts, surn_s, SEEK_CUR);

      //имя
      fread(&name_s, sizeof(name_s), 1, accounts);
      fseek(accounts, name_s, SEEK_CUR);

      //отчество
      fread(&patr_s, sizeof(patr_s), 1, accounts);
      fseek(accounts, patr_s, SEEK_CUR);

      //возраст
      int age;
      fread(&age, sizeof(age), 1, accounts);

      //группа
      fseek(accounts, GROUP_NAME_SIZE, SEEK_CUR);

      //факультет
      fread(&faculty_s, sizeof(faculty_s), 1, accounts);
      fseek(accounts, faculty_s, SEEK_CUR);
    }
  }

  //если логин не найден
  return nullptr;
}

And what's in the menu:
Student * student = getStudentData(accounts, login);
    if (student == nullptr)// Если введённый логин не найден
    {
      showMessage("Entered login is not found.");
      ShowStartMenu();
      ShowLoginStr(login);
      ShowPasswordStr(strlen(password));
      goto Sign_In_Form;
    }
    else if (strcmp(password, student->password) == 0)//если пароли совпадают
    {
      //вход в систему
      //showMessage("Hello, ", student->surname, " ", student->name, ".");
      cout << student->group << endl << student->faculty << endl << student->patronymic << endl;
      cout << student->group << endl << student->faculty << endl << student->patronymic;
    }
    else//если пароль введён неверно
    {
      showMessage("Incorrect password.");
      ShowStartMenu();
      ShowLoginStr(login);
      ShowPasswordStr(strlen(password));
      goto Sign_In_Form;
    }

Repeated cout doesn't work. Why?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
nirvimel, 2016-09-02
@nirvimel

From getStudentDatareturns a pointer to a local object student.

A
Adamos, 2016-09-03
@Adamos

Of course, many things are excusable for students, but why use C ++ like C?
MAX_SURNAME_SIZE is how much? My wife has a double last name (24 characters). Will it fit?
MAX_PASSWORD_SIZE - how much? One of my passwords is a 36-character easy-to-remember, non-guessable phrase.
And just something - to overtake this "FILE * accounts" into a banal XML and read it with something like pugixml.
And no dances with memory and overflow, and no restrictions on the length and language of the field, and no sheets of identical operators, any of which may contain an annoying typo.
And in no way will it reduce the security, if that. Because your binary file is readable by the eyes without any problems ... Passwords are in clear text, I suppose? Hash and salt not passed yet?
And if this code is really used, then the first thing that can be done with it is to translate it into a script on the server. No, I'm not talking about your shitty code - it's easier to rewrite it again ...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question