Загрузка данных


#include "Header.h"

// ========== ОСНОВНЫЕ ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ==========
void SetColor(short int pnTextColor, short int pnBKColor) {
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdOut, (WORD)((pnBKColor & 0x000F) << 4) | (pnTextColor & 0x000F));
}

void SetCursorPosition(short pnRow, short pnCol) {
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD position{ pnCol, pnRow };
    SetConsoleCursorPosition(hStdOut, position);
}

COORD GetCursorPosition() {
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    return csbi.dwCursorPosition;
}

void info() {
    cout << "Зажигин А.К. группа 1бИВТн5 вариант 9\n\n";
}

// ========== ФУНКЦИИ ВВОДА С ESC ==========
bool ReadStringWithESC(string& out) {
    out.clear();
    while (true) {
        if (_kbhit()) {
            int ch = _getch();
            if (ch == 27) {
                cout << endl << endl << "Аварийный выход через ESC!" << endl;
                system("pause");
                return false;
            }
            if (ch == 13) {
                cout << '\n';
                return true;
            }
            if (ch == 8) {
                if (!out.empty()) {
                    out.pop_back();
                    cout << "\b \b";
                }
            }
            else if (ch == 0 || ch == 224) {
                _getch();
            }
            else if ((ch >= 32 && ch <= 126) || (ch >= 128 && ch <= 255)) {
                out += static_cast<char>(ch);
                cout << static_cast<char>(ch);
            }
        }
    }
}

bool ReadIntWithESC(int& val) {
    string s;
    COORD errorPos = { 0, 0 };
    bool errorShown = false;

    while (true) {
        if (!ReadStringWithESC(s)) return false;
        if (s.empty()) continue;

        try {
            size_t pos = 0;
            val = stoi(s, &pos);
            if (pos != s.length()) throw invalid_argument("Остались символы");
            return true;
        }
        catch (...) {
            if (!errorShown) {
                cout << endl;
                errorPos = GetCursorPosition();
                errorShown = true;
            }
            SetCursorPosition(errorPos.Y, errorPos.X);
            SPACEBACK(50);
            SetColor(CL_RED, CL_BLACK);
            cout << "Ошибка! Введите целое число: ";
            SetColor(CL_WHITE, CL_BLACK);
            s.clear();
        }
    }
}

bool ReadDoubleWithESC(double& val) {
    string s;
    COORD errorPos = { 0, 0 };
    bool errorShown = false;

    while (true) {
        if (!ReadStringWithESC(s)) return false;
        if (s.empty()) continue;

        replace(s.begin(), s.end(), '.', ',');

        try {
            size_t pos = 0;
            val = stod(s, &pos);
            if (pos != s.length()) throw invalid_argument("Остались символы");
            return true;
        }
        catch (...) {
            if (!errorShown) {
                cout << endl;
                errorPos = GetCursorPosition();
                errorShown = true;
            }
            SetCursorPosition(errorPos.Y, errorPos.X);
            SPACEBACK(50);
            SetColor(CL_RED, CL_BLACK);
            cout << "Ошибка! Введите число: ";
            SetColor(CL_WHITE, CL_BLACK);
            s.clear();
        }
    }
}

// ========== ЛАБИРИНТ (ВАШ РАБОЧИЙ) ==========
int Labyrinth() {
    system("cls");

    unsigned int map[32]{
      0b00000111111111111111111111111111,
      0b11110111111111111000011111111111,
      0b11110111111111111011011111111111,
      0b11110111111111111011011111111111,
      0b11110111111111100011000011111111,
      0b11110111111111101111011001111111,
      0b11110000000111101111011100011111,
      0b11110111110000001111011111011111,
      0b11110111111101111111011111011111,
      0b11110011111101111111011111011111,
      0b11111011111101111111000011011111,
      0b11111011111101111111111011011111,
      0b11111011111100000000000011011111,
      0b11111011100001111111111000000001,
      0b11111011101111111111111111011111,
      0b11111011101111111111111111011111,
      0b10000000001111111111111111011111,
      0b10110111101111111111111111011111,
      0b10110111101111111111111111011111,
      0b11100000001111111111111111011111,
      0b11101110111111111110000011011111,
      0b11101110111111111000111011011111,
      0b11101110111111110011111011011111,
      0b11101110000111110111111000011111,
      0b11101111110111110111111110011111,
      0b11101111110000000110001111000000,
      0b11101111111111011100100111010111,
      0b11100000011111011101110111000111,
      0b11101111000111000001110111111111,
      0b11101111110111111111000000011111,
      0b11001111110000000000011111011111,
      0b11111111111111111111111111111111
    };

    unsigned int bcur = 0x80000000;

    for (int R = 0; R < 32; R++) {
        for (int C = 0; C < 32; C++) {
            if (map[R] & (bcur >> C)) {
                SetColor(CL_BLUE, CL_BLUE);
                cout << "ШШ";
            }
            else {
                SetColor(CL_BLACK, CL_BLACK);
                cout << "  ";
            }
        }
        SetColor(CL_BLACK, CL_BLACK);
        cout << "\n";
    }

    SetColor(CL_WHITE, CL_BLACK);
    cout << "Лабиринт\nНеобходимо привести жука к желтому выходу\nУправление жуком на стрелочки\nF5 - построить маршрут\nESC - выход\n";

    COORD coord = GetCursorPosition();

    short nR = 0, nC = 0, nER = 25, nEC = 62;

    SetCursorPosition(nER, nEC);
    SetColor(CL_YELLOW, CL_YELLOW);
    cout << "ЖЖ";

    SetCursorPosition(nR, nC);
    SetColor(CL_GREEN, CL_GREEN);
    cout << "ЖЖ";

    unsigned char ch;

    int dist[32][32];
    auto initDist = [&]() {
        for (int i = 0; i < 32; i++)
            for (int j = 0; j < 32; j++)
                dist[i][j] = 999999;
    };

    auto findOptimalPath = [&](int startR, int startC, int endR, int endC) {
        initDist();
        int queue[2000][2];
        int head = 0, tail = 0;

        queue[tail][0] = startR;
        queue[tail][1] = startC;
        tail++;
        dist[startR][startC / 2] = 0;

        int dr[] = { 1, 0, -1, 0 };
        int dc[] = { 0, 2, 0, -2 };

        while (head < tail) {
            int r = queue[head][0];
            int c = queue[head][1];
            head++;

            if (r == endR && c == endC) break;

            for (int i = 0; i < 4; i++) {
                int nr = r + dr[i];
                int nc = c + dc[i];

                if (nr < 0 || nr >= 32 || nc < 0 || nc >= 64) continue;
                if ((nc / 2) < 0 || (nc / 2) >= 32) continue;

                unsigned int mask = 0x80000000 >> (nc / 2);

                if (!(map[nr] & mask) && dist[nr][(nc / 2)] == 999999) {
                    dist[nr][(nc / 2)] = dist[r][(c / 2)] + 1;
                    queue[tail][0] = nr;
                    queue[tail][1] = nc;
                    tail++;
                }
            }
        }
    };

    auto drawOptimalPath = [&](int startR, int startC, int endR, int endC) {
        if (dist[endR][endC / 2] == 999999) {
            cout << "Путь не найден!" << endl;
            return;
        }

        SetColor(CL_GREEN, CL_BLACK);
        int r = endR, c = endC;

        while (r != startR || c != startC) {
            SetCursorPosition(r, c);
            cout << "<>";

            int dr[] = { -1, 0, 1, 0 };
            int dc[] = { 0, -2, 0, 2 };

            for (int i = 0; i < 4; i++) {
                int nr = r + dr[i];
                int nc = c + dc[i];
                int nBit = nc / 2;

                if (nr >= 0 && nr < 32 && nc >= 0 && nc < 64 && nBit >= 0 && nBit < 32) {
                    if (dist[nr][nBit] == dist[r][c / 2] - 1) {
                        r = nr;
                        c = nc;
                        break;
                    }
                }
            }
        }

        SetCursorPosition(startR, startC);
        cout << "<>";
    };

    do {
        SetCursorPosition(nR, nC);
        SetColor(CL_GREEN, CL_GREEN);
        cout << "ЖЖ";
        ch = _getch();
        SetCursorPosition(nR, nC);
        SetColor(CL_BLACK, CL_BLACK);
        cout << "  ";
        switch (ch) {
        case 224:
            switch (ch = _getch()) {
            case 75: if (nC > 0) if (map[nR] & (bcur >> ((nC - 2) / 2))) Beep(750, 300); else nC -= 2; break;
            case 77: if (nC < 64) if (map[nR] & (bcur >> ((nC + 2) / 2))) Beep(750, 300); else nC += 2; break;
            case 72: if (nR > 0) if (map[nR - 1] & (bcur >> (nC / 2))) Beep(750, 300); else nR--; break;
            case 80: if (nR < 31) if (map[nR + 1] & (bcur >> (nC / 2))) Beep(750, 300); else nR++; break;
            };
            break;
        case 0:
            switch (ch = _getch()) {
            case 63: // F5
                findOptimalPath(nR, nC, nER, nEC);
                drawOptimalPath(nR, nC, nER, nEC);
                SetCursorPosition(nER, nEC);
                SetColor(CL_YELLOW, CL_YELLOW);
                cout << "ЖЖ";
                break;
            }
        }
    } while ((ch != 27) && ((nR != nER) || (nC != nEC)));

    SetCursorPosition(coord.Y, coord.X);
    SetColor(CL_LIGHT_WHITE, CL_BLACK);

    ENDL;

    if (ch == 27) {
        cout << endl << "Аварийный выход через ESC!" << endl;
    } else {
        cout << endl << "Жук успешно выведен из лабиринта!" << endl;
    }

    ENDL;
    system("pause");
    return 0;
}

// ========== ЛАБОРАТОРНАЯ РАБОТА 1 (поиск первого и последнего отрицательного) ==========
int Lab1() {
    system("cls");
    info();
    ENDL;
    cout << "Задан массив x[1], x[2], ..., x[15].\n";
    cout << "Определить номер первого отрицательного и номер последнего отрицательного элемента.\n";
    ENDL;

    const int SIZE = 15;
    double x[SIZE];
    cout << "Введите 15 чисел:" << endl;

    COORD coord = GetCursorPosition();

    for (int i = 0; i < SIZE; i++) {
        SetCursorPosition(coord.Y, coord.X);
        SPACEBACK(50);
        cout << "x[" << i + 1 << "] = ";
        if (!ReadDoubleWithESC(x[i])) return 0;
    }

    ENDL;
    cout << "Введённый массив:" << endl;
    for (int i = 0; i < SIZE; i++) {
        cout << "x[" << i + 1 << "] = " << x[i];
        if (i < SIZE - 1) cout << ", ";
        else cout << endl;
    }

    int firstNeg = -1, lastNeg = -1;
    for (int i = 0; i < SIZE; i++) {
        if (x[i] < 0) {
            if (firstNeg == -1) firstNeg = i;
            lastNeg = i;
        }
    }

    ENDL;
    if (firstNeg != -1) {
        cout << "Первый отрицательный элемент: x[" << firstNeg + 1 << "] = " << x[firstNeg] << endl;
        cout << "Последний отрицательный элемент: x[" << lastNeg + 1 << "] = " << x[lastNeg] << endl;
    } else {
        SetColor(CL_RED, CL_BLACK);
        cout << "Отрицательных элементов нет!" << endl;
        SetColor(CL_WHITE, CL_BLACK);
    }

    ENDL;
    system("pause");
    return 0;
}

// ========== ЛАБОРАТОРНАЯ РАБОТА 2 (динамический массив) ==========
int Lab2() {
    system("cls");
    info();
    ENDL;
    cout << "Задан массив x[1], x[2], ..., x[N].\n";
    cout << "Определить номер первого отрицательного и номер последнего отрицательного элемента.\n";
    ENDL;

    int N = 0;
    cout << "Введите количество элементов N: ";
    if (!ReadIntWithESC(N) || N <= 0) {
        SetColor(CL_RED, CL_BLACK);
        cout << "Ошибка: N должно быть положительным целым числом." << endl;
        SetColor(CL_WHITE, CL_BLACK);
        system("pause");
        return 0;
    }

    double* x = new double[N];
    cout << "\nВведите " << N << " чисел:" << endl;

    COORD coord = GetCursorPosition();

    for (int i = 0; i < N; i++) {
        SetCursorPosition(coord.Y, coord.X);
        SPACEBACK(50);
        cout << "x[" << i + 1 << "] = ";
        if (!ReadDoubleWithESC(x[i])) {
            delete[] x;
            return 0;
        }
    }

    ENDL;
    cout << "Введённый массив:" << endl;
    for (int i = 0; i < N; i++) {
        cout << "x[" << i + 1 << "] = " << x[i];
        if (i < N - 1) cout << ", ";
        else cout << endl;
    }

    int firstNeg = -1, lastNeg = -1;
    for (int i = 0; i < N; i++) {
        if (x[i] < 0) {
            if (firstNeg == -1) firstNeg = i;
            lastNeg = i;
        }
    }

    ENDL;
    if (firstNeg != -1) {
        cout << "Первый отрицательный элемент: x[" << firstNeg + 1 << "] = " << x[firstNeg] << endl;
        cout << "Последний отрицательный элемент: x[" << lastNeg + 1 << "] = " << x[lastNeg] << endl;
    } else {
        SetColor(CL_RED, CL_BLACK);
        cout << "Отрицательных элементов нет!" << endl;
        SetColor(CL_WHITE, CL_BLACK);
    }

    delete[] x;
    ENDL;
    system("pause");
    return 0;
}

// ========== ЛАБОРАТОРНАЯ РАБОТА 3 (ФАЙЛ) ==========
int ProcessFile() {
    int CCount = 0;
    string path;
    cout << "Введите название файла (в формате *.txt). Для выхода введите \"*\": ";
    cin.clear();
    cin.ignore(cin.rdbuf()->in_avail());
    getline(cin, path);

    if (path == "*") return 0;

    ifstream fs;
    fs.open(path);
    if (!fs.is_open()) {
        cout << "\nОшибка открытия файла \"" << path << "\"\n";
        cerr << "Детали ошибки: " << strerror(errno) << " (код " << errno << ")" << endl;
        return 1;
    }

    cout << "Файл открыт!" << endl << endl;

    string msg;
    istringstream ss;
    bool error = false;
    streampos errorPos = 0;

    while (!(fs >> ws).eof()) {
        CCount++;
        fs >> msg;
        ss.str(msg);
        ss.clear();
        int nElem;
        ss >> nElem;

        if (ss.fail() || !ss.eof()) {
            errorPos = fs.tellg();
            errorPos = errorPos - (streampos)msg.length();
            error = true;
            break;
        }
    }

    if (CCount == 0) {
        fs.close();
        cout << "Файл не содержит элементов\n\n";
        return 1;
    }

    if (error) {
        cout << "Ошибка: некорректные данные в файле \"" << path << "\"" << endl;
        cout << "Ошибка в элементе под номером - " << CCount << endl;
        cout << "Абсолютная позиция первого символа - " << (int(errorPos)) << endl;
        cout << "Первый символ некорректного элемента - '" << msg[0] << "' (код " << (int)msg[0] << ")" << endl;
        cout << "Некорректный элемент \"" << msg << "\"" << endl;
        if ((ss.rdstate() & ios::eofbit))
            cout << "Слишком большой элемент!\n";
        fs.close();
        return 1;
    }

    fs.close();

    if (CCount <= 5) {
        cout << "Некорректное количество элементов в файле (должно быть более 5)" << endl;
        return 1;
    }

    int* y = new (nothrow) int[CCount];
    if (y == nullptr) {
        cout << "Ошибка выделения памяти под массив\n";
        return 1;
    }

    fs.open(path);
    if (!fs.is_open()) {
        cout << "\nОшибка при работе с файлом.\n";
        delete[] y;
        return 1;
    }

    for (int i = 0; i < CCount; i++) {
        fs >> y[i];
    }
    fs.close();

    cout << "\nПолученный массив:\n";
    for (int i = 0; i < CCount; i++) {
        cout << "y[" << i + 1 << "] = " << y[i] << endl;
    }
    cout << "\n--- ВЫЧИСЛЕНИЕ РЕЗУЛЬТАТА ---\n";

    int firstNeg = -1, lastNeg = -1;
    for (int i = 0; i < CCount; i++) {
        if (y[i] < 0) {
            if (firstNeg == -1) firstNeg = i;
            lastNeg = i;
        }
    }

    if (firstNeg != -1) {
        cout << "Первый отрицательный элемент: y[" << firstNeg + 1 << "] = " << y[firstNeg] << endl;
        cout << "Последний отрицательный элемент: y[" << lastNeg + 1 << "] = " << y[lastNeg] << endl;
    } else {
        SetColor(CL_RED, CL_BLACK);
        cout << "Отрицательных элементов нет!" << endl;
        SetColor(CL_WHITE, CL_BLACK);
    }

    delete[] y;
    return 0;
}

int Lab3() {
    system("cls");
    info();
    cout << "Задание (вариант 9):\n";
    cout << "1. Создать или открыть файл с данными.\n";
    cout << "2. Проверить корректность данных в файле.\n";
    cout << "3. Прочитать данные в массив y.\n";
    cout << "4. Определить номер первого отрицательного и номер последнего отрицательного элемента.\n\n";

    char choice;
    do {
        int result = ProcessFile();
        if (result == 0) {
            cout << endl << "Завершение обработки" << endl << endl;
            break;
        }
        cout << "\nХотите обработать другой файл? (y/n): ";
        choice = _getch();
        if (choice != 'y' && choice != 'Y') break;
    } while (true);

    system("pause");
    return 0;
}

// ========== МАСКА ==========
int MASKA() {
    system("cls");
    info();
    ENDL;
    cout << "Задан массив y[1], y[2], ..., y[20]. Определить, какие значения массива соответствуют маске (01010100)." << endl;
    ENDL;

    const int SIZE = 20;
    short mas[SIZE];
    short maska = 0x54;

    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<short> dist(600, 3000);

    for (int i = 0; i < SIZE; i++) {
        mas[i] = dist(gen);
    }

    cout << "Сгенерированный массив:" << endl << "[";
    for (int i = 0; i < SIZE; i++) {
        cout << mas[i] << (i < SIZE - 1 ? ", " : "]\n");
    }
    ENDL;

    cout << "Среди всех значений массива маске (01010100) соответствуют следующие значения:" << endl;
    bool found = false;
    for (int i = 0; i < SIZE; i++) {
        if ((mas[i] & maska) == maska) {
            cout << mas[i] << " ";
            found = true;
        }
    }
    if (!found) {
        SetColor(CL_RED, CL_BLACK);
        cout << "Нет подходящих значений.";
        SetColor(CL_WHITE, CL_BLACK);
    }

    ENDL;
    system("pause");
    return 0;
}

// ========== МАКРОСЫ ==========
int Macros() {
    system("cls");
    info();
    ENDL;
    cout << "В данном задании представлено использование макросов, выделяющих старшие и младшие биты числа,\n";
    cout << "а также меняющих их местами. Ниже представлены четыре переменные с разными размерами.\n";
    cout << "Их значения даны через \"/\" (сначала значение в десятичной системе, потом в шестнадцатеричной).\n";
    cout << "После этого идёт размер переменной и использование на ней макросов:\n";
    ENDL;

    const unsigned char B = 230;
    const unsigned short Sh = 15678;
    const unsigned int I = 564872844;
    const unsigned long long LL = 9903331736939477691ULL;

    ENDL;
    cout << "unsigned char: " << dec << (int)B << " / 0x" << hex << (int)B << dec << endl;
    cout << "-- Размер: " << sizeof(B) << " байт" << endl;
    cout << "Hi  = 0x" << hex << Hi(B) << "\n";
    cout << "Lo  = 0x" << hex << Lo(B) << "\n";
    cout << "Swap = 0x" << hex << Swap(B) << dec << endl;

    ENDL;
    cout << "unsigned short: " << dec << Sh << " / 0x" << hex << Sh << dec << endl;
    cout << "-- Размер: " << sizeof(Sh) << " байта" << endl;
    cout << "Hi  = 0x" << hex << Hi(Sh) << "\n";
    cout << "Lo  = 0x" << hex << Lo(Sh) << "\n";
    cout << "Swap = 0x" << hex << Swap(Sh) << dec << endl;

    ENDL;
    cout << "unsigned int: " << dec << I << " / 0x" << hex << I << dec << endl;
    cout << "-- Размер: " << sizeof(I) << " байта" << endl;
    cout << "Hi  = 0x" << hex << Hi(I) << "\n";
    cout << "Lo  = 0x" << hex << Lo(I) << "\n";
    cout << "Swap = 0x" << hex << Swap(I) << dec << endl;

    ENDL;
    cout << "unsigned long long: " << dec << LL << " / 0x" << hex << LL << dec << endl;
    cout << "-- Размер: " << sizeof(LL) << " байт" << endl;
    cout << "Hi  = 0x" << hex << Hi(LL) << "\n";
    cout << "Lo  = 0x" << hex << Lo(LL) << "\n";
    cout << "Swap = 0x" << hex << Swap(LL) << dec << endl;

    ENDL;
    system("pause");
    return 0;
}

// ========== ШИФРОВАНИЕ (ВЕРСИЯ ИЗ КОДА ДРУГА) ==========
int Incryption_byte(int len, unsigned char ch, char* txt) {
    system("cls");
    info();
    unsigned char* p = (unsigned char*)txt;
    for (int i = 0; i < len; i++) {
        p[i] <<= 1;
        if (i < len - 1) {
            p[i] |= (p[i + 1] & 0x80) >> 7;
        }
    }
    p[len - 1] |= (ch >> 7);