C Читання структури з файлу

2075 / C / Struct / Читання структури з файлу


// VS 2019
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <io.h>
#include <fcntl.h>
#include <stdlib.h>

using namespace std;

struct Transport 
{
  char vyd[10];
  char marshrut[10];
  float protyazhnist;
  int chas;
};

int SMON = 28;
static int file; /* файл-таблиця */

/**** Відкрити чи створити файл ****/

void initf(char* fname) {
  if (_access(fname, 0) < 0) {
    /* не існує файлу - створити */
    _fmode = O_BINARY;
    if ((file = _creat(fname, S_IREAD | S_IWRITE)) < 0) 
    {
      printf("Can't create file %s\n", fname);
      _getch();
    }
  }
  else /* існує файл - відкрити */
  {
    if ((file = _open(fname, O_RDWR | O_BINARY)) < 0) {
      printf("Can't open file %s\n", fname);
      _getch();
    }
  }
}

/**** закрити файл ***/
void commit() {
  _close(file);
}

/**** додати в кінець файлу ****/
void f_add(Transport* a) {
  _lseek(file, 0, SEEK_END);
  _write(file, a, SMON);
}

/**** перевірка ****/
int fcheck_number(int n) {
  long nn;
  if (n < 1) {
    printf("Мінімальний номер : 1\n");
    return -1;
  }
  nn = _lseek(file, 0, SEEK_END) / SMON;
  if (n > nn) {
    printf("Максимальний номер :%d\n", (int)nn);
    return -1;
  }
  return 0;
}

void show_1(Transport* x) {
  cout << "Vyd: " << x->vyd << endl;
  cout << "Marshrut: " << x->marshrut << endl;
  cout << "Protyazhnist: " << x->protyazhnist << endl;
  cout << "Chas: " << x->chas << endl << endl;
}

/**** виведення одного запису ****/
void fshow_1(int n) {
  long t;
  Transport x;
  t = n - 1; t *= SMON;
  _lseek(file, t, SEEK_SET);
  _read(file, &x, SMON);
  show_1(&x);
}

/**** виведення усіх записів ****/
void fshow_all() {
  Transport x;
  _lseek(file, 0, SEEK_SET);
  // print_head();
  while (_read(file, &x, SMON)) {
    show_1(&x);
  }
}

/**** видалення запису ****/
void fdel_item(int n) {
  long t;
  Transport x;
  t = n; 
  t *= SMON;
  _lseek(file, t, SEEK_SET);
  while (_read(file, &x, SMON)) {
    t = _lseek(file, t - SMON, SEEK_SET);
    _write(file, &x, SMON);
    t = _tell(file);
    t = _lseek(file, SMON, SEEK_CUR);
  }
  _chsize(file, t - SMON);
}

/**** главна функція ****/
int main() {
  setlocale(LC_ALL, "Ukrainian");
  Transport x;
  int op; /* операція */
  int num; /* номер елемента */
  char eoj; /* кінець файлу */
  char file[] = "1.txt";

  /* відкриття файлу */

  initf(file);

  for (eoj = 0; !eoj; ) {
    /* вивод меню */
    printf("1 - Додати елемент\n");
    printf("2 - Видалити елемент\n");
    printf("3 - Показати елемент за номером\n");
    printf("4 - Показати все\n");
    printf("0 - Вийти\n");
    printf("Введiть >");

    /* вибір меню */
    scanf("%d", &op);
    switch (op) {
      case 0:
        eoj = 1;
        break;
      case 1: /* додати */
        cout << "Vyd: ";
        cin.ignore();
        _flushall();
        cin.getline(x.vyd, sizeof(x.vyd));
        cout << "Marshrut: ";
        cin.getline(x.marshrut, sizeof(x.marshrut));
        cout << "Protyazhnist: ";
        scanf("%f", &x.protyazhnist);
        cout << "Chas: ";
        scanf("%i", &x.chas);
        f_add(&x);
        break;
      case 2: /* видалити */
        cout << "Vvedit nomer: ";
        scanf("%i", &num);
        if (fcheck_number(num) != -1) {
          fdel_item(num);
        }
        break;
      case 3: /* показати один */
        cout << "Vvedit nomer: ";
        scanf("%i", &num);
        if (fcheck_number(num) != -1) {
          fshow_1(num);
        }

        break;
      case 4: /* показати все */
        fshow_all();
        break;
      default:
        printf("Неправильна операцiя\n");
        break;
    }

    if (op) {
      printf("Натиснiть будь-яку клавiшу\n");
      _getch();
    } /* if */
  } /* for */

  /* закрити файл */
  commit();
  return 0;
} /* main */