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


// ========== ЛАБОРАТОРНАЯ РАБОТА 1 (СТАТИЧЕСКИЙ МАССИВ) ==========
int Lab1_Static() {
    system("cls");
    info();
    SetColor(11, 0);
    cout << "===============================================================================\n";
    cout << "Лабораторная работа №1 (Статический массив)\n";
    cout << "===============================================================================\n";
    SetColor(7, 0);
    cout << "Задача: Задан массив x1, x2, …, x15 (15 элементов).\n";
    cout << "        Определить номер первого отрицательного xi и номер последнего\n";
    cout << "        отрицательного xi.\n";
    cout << "===============================================================================\n\n";
    SetColor(7, 0);

    const int SIZE = 15;
    double arr[SIZE];
    cout << "Введите 15 чисел:\n";
    COORD coord = GetCursorPosition();

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

    // Вывод массива в столбик
    cout << "\nМассив:\n";
    for (int i = 0; i < SIZE; i++) {
        cout << "  x[" << i + 1 << "] = " << arr[i] << endl;
    }

    int firstNeg = -1;
    for (int i = 0; i < SIZE; i++) {
        if (arr[i] < 0) {
            firstNeg = i + 1;
            break;
        }
    }

    int lastNeg = -1;
    for (int i = SIZE - 1; i >= 0; i--) {
        if (arr[i] < 0) {
            lastNeg = i + 1;
            break;
        }
    }

    if (firstNeg == -1) {
        cout << "\nВ массиве нет отрицательных чисел.\n";
    }
    else {
        cout << "\nНомер первого отрицательного: " << firstNeg << endl;
        cout << "Номер последнего отрицательного: " << lastNeg << endl;
    }

    cout << "\nНажмите любую клавишу для возврата в меню...";
    (void)_getch();
    return 0;
}

// ========== ЛАБОРАТОРНАЯ РАБОТА 2 (ДИНАМИЧЕСКИЙ МАССИВ) ==========
int Lab2_Dynamic() {
    system("cls");
    info();
    SetColor(11, 0);
    cout << "===============================================================================\n";
    cout << "Лабораторная работа №2 (Динамический массив)\n";
    cout << "===============================================================================\n";
    SetColor(7, 0);
    cout << "Задача: Задан массив x1, x2, …, xN (размер N вводит пользователь).\n";
    cout << "        Определить номер первого отрицательного xi и номер последнего\n";
    cout << "        отрицательного xi.\n";
    cout << "===============================================================================\n\n";
    SetColor(7, 0);

    int N;
    cout << "Введите количество элементов массива N: ";
    if (!ReadIntWithESC(N) || N <= 0) return 0;

    double* arr = new double[N];
    cout << "Введите " << N << " чисел:\n";
    COORD coord = GetCursorPosition();
    for (int i = 0; i < N; i++) {
        SetCursorPosition(coord.Y, coord.X);
        SPACEBACK(50);
        cout << "x[" << i + 1 << "] = ";
        if (!ReadDoubleWithESC(arr[i])) { delete[] arr; return 0; }
    }

    // Вывод массива в столбик
    cout << "\nМассив:\n";
    for (int i = 0; i < N; i++) {
        cout << "  x[" << i + 1 << "] = " << arr[i] << endl;
    }

    int firstNeg = -1;
    for (int i = 0; i < N; i++) {
        if (arr[i] < 0) {
            firstNeg = i + 1;
            break;
        }
    }

    int lastNeg = -1;
    for (int i = N - 1; i >= 0; i--) {
        if (arr[i] < 0) {
            lastNeg = i + 1;
            break;
        }
    }

    if (firstNeg == -1) {
        cout << "\nВ массиве нет отрицательных чисел.\n";
    }
    else {
        cout << "\nНомер первого отрицательного: " << firstNeg << endl;
        cout << "Номер последнего отрицательного: " << lastNeg << endl;
    }

    delete[] arr;
    cout << "\nНажмите любую клавишу для возврата в меню...";
    (void)_getch();
    return 0;
}

// ========== ЛАБОРАТОРНАЯ РАБОТА 3 (ФАЙЛОВЫЙ ВВОД, ДИНАМИЧЕСКИЙ МАССИВ) ==========
int Lab3_File() {
    system("cls");
    info();
    SetColor(11, 0);
    cout << "===============================================================================\n";
    cout << "Лабораторная работа №3 (Файловый ввод, динамический массив)\n";
    cout << "===============================================================================\n";
    SetColor(7, 0);
    cout << "Задача: Прочитать из файла массив чисел. Первое число файла – размер N,\n";
    cout << "        затем N чисел. Определить номер первого отрицательного элемента\n";
    cout << "        и номер последнего отрицательного. Предусмотреть произвольный\n";
    cout << "        доступ к элементам по индексу.\n";
    cout << "===============================================================================\n\n";
    SetColor(7, 0);

    string path;
    cout << "Введите название файла (например, 1.txt): ";
    if (!ReadStringWithESC(path)) return 0;
    if (path.empty()) {
        cout << "Имя файла не может быть пустым.\n";
        system("pause");
        return 1;
    }

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

    // Чтение размера массива (первое число)
    int N = 0;
    fs >> N;
    if (fs.fail() || N <= 0) {
        cout << "Ошибка: некорректный размер массива. Ожидается положительное целое число.\n";
        system("pause");
        return 1;
    }

    double* arr = new (nothrow) double[N];
    if (!arr) {
        cout << "Ошибка выделения памяти.\n";
        system("pause");
        return 1;
    }

    // Чтение N чисел с проверкой корректности
    bool error = false;
    for (int i = 0; i < N; i++) {
        string token;
        if (!(fs >> token)) {
            cout << "Ошибка: недостаточно чисел в файле (ожидалось " << N 
                 << ", прочитано " << i << ").\n";
            error = true;
            break;
        }
        for (char& c : token) if (c == '.') c = ',';
        size_t pos = 0;
        try {
            arr[i] = stod(token, &pos);
            if (pos != token.length())
                throw invalid_argument("trailing characters");
        }
        catch (...) {
            cout << "Ошибка: элемент " << i+1 << " (\"" << token 
                 << "\") не является числом.\n";
            error = true;
            break;
        }
    }

    if (error) {
        delete[] arr;
        system("pause");
        return 1;
    }

    // Вывод массива в столбик
    cout << "\nМассив:\n";
    for (int i = 0; i < N; i++) {
        cout << "  x[" << i + 1 << "] = " << arr[i] << endl;
    }

    // Поиск первого и последнего отрицательного
    int firstNeg = -1, lastNeg = -1;
    for (int i = 0; i < N; i++) {
        if (arr[i] < 0) {
            if (firstNeg == -1) firstNeg = i + 1;
            lastNeg = i + 1;
        }
    }

    cout << "\nРезультат:\n";
    if (firstNeg == -1) {
        cout << "Отрицательные элементы отсутствуют.\n";
    }
    else {
        cout << "Номер первого отрицательного: " << firstNeg << endl;
        cout << "Номер последнего отрицательного: " << lastNeg << endl;
    }

    // Произвольный доступ
    cout << "\nДемонстрация произвольного доступа.\n";
    while (true) {
        cout << "Введите номер элемента (1.." << N << "): ";
        int idx;
        if (!ReadIntWithESC(idx)) break;
        if (idx >= 1 && idx <= N) {
            cout << "  arr[" << idx << "] = " << arr[idx - 1] << endl;
        }
        else {
            SetColor(12, 0);
            cout << "Ошибка! Допустимый диапазон: 1.." << N << "\n";
            SetColor(7, 0);
        }
    }

    delete[] arr;
    cout << "\nНажмите любую клавишу для возврата в меню...";
    (void)_getch();
    return 0;
}

// ========== МАКРОСЫ ==========
int Macros() {
    system("cls");
    info();
    // Шапка в стиле лабораторных
    SetColor(11, 0);
    cout << "===============================================================================\n";
    cout << "Задание: Макросы Hi, Lo, Swap\n";
    cout << "===============================================================================\n";
    SetColor(7, 0);
    cout << "Задача: Даны макросы Hi(x), Lo(x), Swap(x), которые выделяют старшую\n";
    cout << "        и младшую половины битов числа, а также меняют их местами.\n";
    cout << "        Продемонстрировать их работу на примере 8-, 16-, 32- и 64-битных\n";
    cout << "        целых чисел.\n";
    cout << "===============================================================================\n\n";
    SetColor(7, 0);

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

    // Вспомогательная лямбда для вывода битовой строки
    auto printBits = [](unsigned long long val, int bits) {
        for (int i = bits - 1; i >= 0; i--) {
            if (i % 8 == 7 && i != bits - 1) cout << ' ';
            cout << ((val >> i) & 1);
        }
    };

    // Структура для удобного перебора
    struct {
        string name;
        string sizeStr;
        unsigned long long value;
        int bits;
    } types[] = {
        {"byte",      "1 байт",  B,  8 },
        {"short",     "2 байта", Sh, 16},
        {"integer",   "4 байта", I,  32},
        {"long long", "8 байт",  LL, 64}
    };

    for (const auto& t : types) {
        // Заголовок типа
        SetColor(14, 0);
        cout << "----------- " << t.name << " (" << t.sizeStr << ", " << t.bits << " бит) -----------\n";
        SetColor(7, 0);

        // Вывод значения
        SetColor(15, 0); cout << "  Десятичное:      "; SetColor(10, 0);
        cout << setw(22) << t.value << endl;
        SetColor(15, 0); cout << "  Шестнадцатеричное: "; SetColor(10, 0);
        cout << "0x" << setfill('0') << setw(t.bits / 4) << hex << uppercase << t.value << dec << nouppercase << setfill(' ') << endl;
        SetColor(15, 0); cout << "  Двоичное:        "; SetColor(10, 0);
        printBits(t.value, t.bits);
        cout << endl << endl;

        // Вычисление результатов макросов
        unsigned long long hi = 0, lo = 0, sw = 0;
        int half = t.bits / 2;
        if (t.bits == 8) {
            hi = Hi((unsigned char)t.value);
            lo = Lo((unsigned char)t.value);
            sw = Swap((unsigned char)t.value);
        } else if (t.bits == 16) {
            hi = Hi((unsigned short)t.value);
            lo = Lo((unsigned short)t.value);
            sw = Swap((unsigned short)t.value);
        } else if (t.bits == 32) {
            hi = Hi((unsigned int)t.value);
            lo = Lo((unsigned int)t.value);
            sw = Swap((unsigned int)t.value);
        } else {
            hi = Hi(t.value);
            lo = Lo(t.value);
            sw = Swap(t.value);
        }

        // Hi
        SetColor(15, 0); cout << "  Hi (старшие " << half << " бит):   ";
        SetColor(11, 0); cout << "0x" << setfill('0') << setw(half / 4) << hex << uppercase << hi << dec << nouppercase << setfill(' ');
        cout << "  ->  ";
        SetColor(8, 0); printBits(t.value >> half, half); cout << endl;

        // Lo
        SetColor(15, 0); cout << "  Lo (младшие " << half << " бит):   ";
        SetColor(11, 0); cout << "0x" << setfill('0') << setw(half / 4) << hex << uppercase << lo << dec << nouppercase << setfill(' ');
        cout << "  ->  ";
        SetColor(8, 0); printBits(lo, half); cout << endl;

        // Swap
        SetColor(15, 0); cout << "  Swap (обмен):      ";
        SetColor(9, 0);  cout << "0x" << setfill('0') << setw(t.bits / 4) << hex << uppercase << sw << dec << nouppercase << setfill(' ');
        cout << "  ->  ";
        SetColor(8, 0); printBits(sw, t.bits); cout << endl;

        cout << endl; // отступ между типами
    }

    SetColor(8, 0);
    cout << "===============================================================================\n";
    cout << "Hi – старшая половина битов, Lo – младшая, Swap – обмен половин местами.\n";
    cout << "===============================================================================\n";
    SetColor(7, 0);

    system("pause");
    return 0;
}