Проблема в считывании структуры из типизированного файла

Снизу реализация очереди на основе типизированного файла - с коррекцией неверного времени и поиском определенных заказов (в промежутке времени от и до). Проблема появляется в функции Pop, которая забирает элемент из файла и сдвигает указатель начала - вместо названий и времени заказов считываются пустота и 0 соответственно, КРОМЕ последнего, сколько бы я не вводил. Почему так происходит, понять не могу, уже всю программу перекроил, поэтому где-то код может быть странным или неуместным.

#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <windows.h>
#include <string.h>
#include <conio.h>
#include <cctype>


struct TZak { //Создаём структуру, в которой находится информация
    char name[31]; //Название заказа
    int h; //Часы
    int m; //Минуты
    int s; //Секунды
};


struct TQ {
    FILE* Q; //Файл для очереди
    int Q_begin = NULL, Q_end = NULL; //Начало первого и последнего элемента в битах
};

bool Empty(TQ Q) { //Проверка на пустоту
    return (Q.Q_begin == Q.Q_end); // Если ссылки на начало и конец пустые значит очередь пустая.
}

void Create(TQ& Q, TZak Zakaz) {//Создание очереди из одного элемента
    Q.Q = fopen("tip.bin", "wb");
    fwrite(&Zakaz, sizeof(TZak), 1, Q.Q); //Помещаем элемент в очередь
    Q.Q_begin = 0;
    Q.Q_end = sizeof(TZak); //Cмещаем указатель конца
    fclose(Q.Q);
    return;
}

void Push(TQ& Q, TZak Zakaz) { //Добавление элемента в конец очереди
    Q.Q = fopen("tip.bin", "w+b");
    fseek(Q.Q, Q.Q_end, SEEK_SET); 
    fwrite(&Zakaz, sizeof(TZak), 1, Q.Q); // Мы получаем элемент и помещаем его в конец очереди
    Q.Q_end += sizeof(TZak); //Cмещаем указатель конца
    fclose(Q.Q);
    return;
}

TZak Pop(TQ& Q) { //Взятие элемента из очереди
    Q.Q = fopen("tip.bin", "rb");
    TZak Elem;
    fseek(Q.Q, Q.Q_begin, SEEK_SET);
    fread(&Elem, sizeof(TZak), 1, Q.Q); //  Мы получаем элемент
    Q.Q_begin += sizeof(TZak);
    fclose(Q.Q);
    return Elem;
}

void outLOG(TQ Q, FILE* log) { //Вывод очереди в лог
    Q.Q = fopen("tip.bin", "rb");
    fseek(Q.Q, 0, SEEK_SET);
    for (int i = 0; i < (Q.Q_end/ sizeof(TZak)); i++) { //поочерёдно читаем элементы из очереди
        TZak* Zakaz = new TZak;
        fread(Zakaz, sizeof(TZak), 1, Q.Q);
        fprintf(log, "\nНазвание: %s Время: %d:%d:%d\n------------------------\n",
            Zakaz->name, Zakaz->h, Zakaz->m,
            Zakaz->s);
    }
    fprintf(log, "\n");
    fclose(Q.Q);
    return;
}

void AddTxt(TQ& Q) { //добавить элементы из текстового файла
    FILE* f;
    TZak Zakaz;
    char s[3];
    int kol = 0;
    if ((f = fopen("vvod.txt", "rt")) == NULL) { //проверка открытия
        printf("Не удалось открыть файл для считывания\nPress any key");
        _getch();
        return;
    }
    while (1) { //циклически считываем элементы
        fscanf(f, "%30s", Zakaz.name);
        if (strcmp(Zakaz.name, "**") == 0 || feof(f)) break;
        fscanf(f, "\n");
        fscanf(f, "%s", s); Zakaz.h = atoi(s);
        if (Zakaz.h < 0) { Zakaz.h = 0; } //коррекция
        if (Zakaz.h > 23) { Zakaz.h = 23; }
        fscanf(f, "%s", s); Zakaz.m = atoi(s);
        if (Zakaz.m < 0) { Zakaz.m = 0; }
        if (Zakaz.m > 59) { Zakaz.m = 59; }
        fscanf(f, "%s", s); Zakaz.s = atoi(s);
        if (Zakaz.s < 0) { Zakaz.s = 0; }
        if (Zakaz.s > 59) { Zakaz.s = 59; }
        if (Empty(Q)) //проверка на пустоту очереди, если ее нет - создаем, если есть - переносим туда элементы
            Create(Q, Zakaz);
        else
            Push(Q, Zakaz);
        kol++;
    }
    fclose(f);
    printf("Введено %d элементов\nPress any key", kol);
    _getch();
    return;
}

void AddElem(TQ& Q) { //добавление элемента вручную
    TZak Zakaz;
    printf("Название:"); scanf("%30s", Zakaz.name);
    printf("Часы:"); scanf("%d", &Zakaz.h);
    printf("Минуты:"); scanf("%d", &Zakaz.m);
    printf("Секунды:"); scanf("%d", &Zakaz.s);
    if (Zakaz.h < 0) { Zakaz.h = 0; } //коррекция
    if (Zakaz.h > 23) { Zakaz.h = 23; }
    if (Zakaz.m < 0) { Zakaz.m = 0; }
    if (Zakaz.m > 59) { Zakaz.m = 59; }
    if (Zakaz.s < 0) { Zakaz.s = 0; }
    if (Zakaz.s > 59) { Zakaz.s = 59; }
    if (Empty(Q)) //проверка на пустоту очереди, если ее нет - создаем, если есть - переносим туда элементы
        Create(Q, Zakaz);
    else
        Push(Q, Zakaz);
    printf("Запись введена\nPress any key");
    _getch();
    return;
}

void PopN(TQ& Q, int N) { //удаляет N элементов очереди
    int i = 0;
    TZak Zakaz;
    while ((!Empty(Q)) && (i < N)) { //цикилчески удаляем N элементов
        Zakaz = Pop(Q);
        i++;
    }
    return;
}

char* ANSIUpperCase(char* s, char* S) { //функция, необходимая для поиска нужных
    S = strcpy(S, s);
    char* ch = S;
    while (*ch) {
        if (*ch >= 'a' && *ch <= 'z' || *ch >= 'а' && *ch <= 'я') *ch = *ch - 32;
        if (*ch == 'ё') *ch = 'Ё';
        ch++;
    }
    return S;
}

void Filter(TQ Q_main, TQ& Q_correct) { //Функция фильтра
    TZak Zakaz;
    char SUp[31];
    while (!Empty(Q_main)) { //все элементы очереди извлекаем
        Zakaz = Pop(Q_main);
        if ((Zakaz.h == 15 && Zakaz.m == 20 && Zakaz.s >= 35) || (Zakaz.h == 15 && Zakaz.m > 20) ||
            (Zakaz.h > 15 && Zakaz.h < 18) || (Zakaz.h == 18 && Zakaz.m < 50) || (Zakaz.h == 18 && Zakaz.m == 50 && Zakaz.s <= 10)) //оставляем только те, которые удовлетворяют условию
        {
            if (Empty(Q_correct))
                Create(Q_correct, Zakaz);
            else
                Push(Q_correct, Zakaz);
        }
    }
    return;
}




int main()
{
    char ch;
    FILE* log;
    TQ Q_1, Q_2;
    int n;
    SetConsoleOutputCP(1251);
    SetConsoleCP(1251);
    do {
        log = fopen("log.txt", "a"); //Открытие лог файла
        printf("\nN - Добавить элемент в очередь c клавиатуры;\nT - Добавить элемент в очередь из текстового файла;\nD - Удалить N элементов очереди;\nR - Удалить неудовлетворяющие элементы;\nF - Освободить очередь;\nE - Выход;\nВаш выбор?");
        scanf("\n");
        ch = getchar(); fflush(stdin);
        ch = toupper(ch);
        switch (ch) { //Интерактивный выбор в меню
        case 'N': AddElem(Q_1); outLOG(Q_1, log); //добавляем элемент вручную, выводим в лог

            break;
        case 'T': AddTxt(Q_1); outLOG(Q_1, log); //добавляем элемент из текстового, выводим в лог
            break;
        case 'D': //удаляем N элементов
            printf("Введите N:"); scanf("%d", &n);
            PopN(Q_1, n); outLOG(Q_1, log);
            break;
        case 'R': //фильтр
            Filter(Q_1, Q_2);
            fprintf(log, "Искомая очередь:\n");
            Q_1 = Q_2;
            if (!Empty(Q_2))
                outLOG(Q_2, log);
            else
                fprintf(log, "Пусто\n");
            break;
        case 'E': return 0; //выход
        default:
            printf("Нет такой команды\nPress any key");
            _getch();
        }
        fclose(log);
    } while (ch != 'E');

    return 0;
}

Ответы (0 шт):