#include <iostream>
#include <string>
#include <vector>
#include <random>
#include "Log.h"
#include "Log.cpp"
#include "Passgen.h"

using namespace std;

#ifndef PASSGEN
#define PASSGEN

class Options {
    public:
    virtual bool lower() const = 0;
    virtual bool upper() const = 0;
    virtual bool nums() const = 0;
    virtual bool specchars() const = 0;
    virtual int len() const = 0;
};

class Fabric {
    public:
    virtual string gen_password() const = 0;
};

class PassOptions : public Options {
    bool addlower;
    bool addupper;
    bool addnums;
    bool addspec;
    int passlen;

    public:
    PassOptions(bool lower, bool upper, bool nums, bool spec, int len)
        : addlower(lower), addupper(upper), addnums(nums), addspec(spec), passlen(len) {}

    bool lower() const override { 
        return addlower; 
    }

    bool upper() const override { 
        return addupper; 
    }

    bool nums() const override { 
        return addnums; 
    }

    bool specchars() const override { 
        return addspec; 
    }

    int len() const override { 
        return passlen; 
    }
};

class PassFabric : public Fabric {

    Options &options;

    char randchar(string &symbols) const {
        return symbols[rand() % symbols.length()];
    }

    public:
    PassFabric(Options &opts) : options(opts) {}

    string gen_password() const override {
        Log::get_ekzempl().write("ИНФО", "Запущен процесс ввода параметров");
        string add_chars, password;
        if(options.lower()) 
            add_chars += "abcdefghijklmnopqrstuvwxyz";
        if(options.upper()) 
            add_chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        if(options.nums()) 
            add_chars += "0123456789";
        if(options.specchars()) 
            add_chars += "!@#$%^&*()_-+=<>?";
        Log::get_ekzempl().write("ИНФО", "Запущен процесс ввода параметров");
        if(add_chars.empty()) {
            throw runtime_error("Символы для генерации пароля не выбраны");
        }
        for(int i = 0; i < options.len(); ++i) {
            password += randchar(add_chars);
        }
        return password;
    }
};

class Com {
    public:
    virtual void generate() = 0;
};

class PassGenCom : public Com {
    
    vector<string> passwords;
    Fabric &fabric;
    int passwords_count;

    public:
    PassGenCom(Fabric &f, int pass_count, vector<string> p)
        : fabric(f), passwords_count(pass_count), passwords(p) {}

    void generate() override {
        srand(time(nullptr));
        Log::get_ekzempl().write("ИНФО", "Запущен процесс ввода параметров");
        try {
            for(int i = 0; i < passwords_count; ++i)
                passwords.push_back(fabric.gen_password());
        } catch(exception err) {
            throw runtime_error(err.what());
        }
    }
};

class PassCheck {
public:
    static bool normal_password(string password) {
        int good = 0;
        Log::get_ekzempl().write("ИНФО", "Запущен процесс ввода параметров");
        for(char c: password) {
            if(islower(c) || isupper(c)) 
                good += 2;
            else if(isdigit(c)) 
                good += 2;
            else 
                good += 3;
        }
        return good > 16;
    }
};

class Program {

    // пользоват. ввод параметров генерации паролей
    PassOptions writePassOptions() {
        bool lower, upper, nums, specsyms;
        int len;
        Log::get_ekzempl().write("ИНФО", "Запущен процесс ввода параметров");
        cout << "Cтрочные буквы (1 да, 0 нет): ";
        cin >> lower;
        cout << "Заглавные буквы (1 да, 0 нет): ";
        cin >> upper;
        cout << "Цифры (1 да, 0 нет): ";
        cin >> nums;
        cout << "Спецсимволы (1 да, 0 нет): ";
        cin >> specsyms;
        cout << "Длина пароля(ей): ";
        cin >> len;
        Log::get_ekzempl().write("ИНФО", "Ввод параметров завершен");
        return PassOptions(lower, upper, nums, specsyms, len);
    }

    public:
    Program() {

        int passwdcount;
        bool loop;
        vector<string> passwords;
        Log::get_ekzempl().write("ИНФО", "Программа запущена");
        while(true) { // рабочий цикл программы
            try {
                cout << "Генератор паролей" << endl;
                Log::get_ekzempl().write("ИНФО", "Ввод количества паролей");
                PassOptions options = writePassOptions();
                PassFabric PassFabric(options);
                cout << "Кол-во генерируемых паролей: ";
                cin >> passwdcount;
                
                if(passwdcount <= 0) {
                    Log::get_ekzempl().write("ОШИБКА", "Введено кол-во паролей < 0");
                    throw runtime_error("Количество паролей должно быть больше нуля!");
                }
                
                Log::get_ekzempl().write("ИНФО", "Генерация паролей");
                PassGenCom com(PassFabric, passwdcount, passwords);
                com.generate();
                
                Log::get_ekzempl().write("ИНФО", "Вывод и проверка паролей на надежность");
                for(string password: passwords) {
                    cout << password;
                    if(PassCheck::normal_password(password))
                        cout << " (надежный)";
                    else
                        cout << " (не надежный)";
                    cout << endl;
                }
                passwords.clear();

                cout << endl << "Сгенерировать еще пароли (1 да, 0 нет): ";
                cin >> loop;
                if(!loop) 
                    break;
            } catch(exception err) {
                cout << "Ошибка: " << err.what() << endl;
                Log::get_ekzempl().write("ОШИБКА", err.what());
                cin.clear();
                cin.ignore(128, '\n');
            }
        }
    }

};

int main() {

    Program program;
    return 0;
}

Программа на C++ не выводит список паролей:
Сгенерировать еще пароли (1 да, 0 нет): 1
Генератор паролей
Cтрочные буквы (1 да, 0 нет): 1
Заглавные буквы (1 да, 0 нет): 1
Цифры (1 да, 0 нет): 1
Спецсимволы (1 да, 0 нет): 1
Длина пароля(ей): 10
Кол-во генерируемых паролей: 10

Сгенерировать еще пароли (1 да, 0 нет):

Помоги найти ошибку