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


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

/* ------------------- Глобальные переменные для консоли ------------------- */

HANDLE hConsole;                     // дескриптор консоли
CONSOLE_SCREEN_BUFFER_INFO startInfo; // для сохранения исходных атрибутов
WORD defaultAttributes;              // исходный цвет консоли

/* ------------------------ Работа с цветом консоли ------------------------ */

void setColorNormal() {
    // Белый текст на чёрном фоне
    SetConsoleTextAttribute(hConsole,
        FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}

void setColorTitle() {
    // Ярко‑жёлтый текст
    SetConsoleTextAttribute(hConsole,
        FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
}

void setColorError() {
    // Ярко‑красный текст
    SetConsoleTextAttribute(hConsole,
        FOREGROUND_RED | FOREGROUND_INTENSITY);
}

/* ---------------------- Ввод целого положительного N --------------------- */

int inputPositiveInt(const char *prompt, int maxValue) {
    double tmp;
    int ok = 0;
    int c;

    while (!ok) {
        setColorNormal();
        printf("%s", prompt);

        if (scanf("%lf", &tmp) != 1) {
            // очистить буфер
            while ((c = getchar()) != '\n' && c != EOF) {}
            setColorError();
            printf("Ошибка ввода. Введите целое число.\n");
            continue;
        }
        // очистить хвост строки (например, если ввели 5abc)
        while ((c = getchar()) != '\n' && c != EOF) {}

        if (tmp <= 0 || tmp > maxValue || (int)tmp != tmp) {
            setColorError();
            printf("Размер должен быть ЦЕЛЫМ числом от 1 до %d.\n", maxValue);
            continue;
        }
        ok = 1;
    }
    return (int)tmp;
}

/* ------------------------ Ввод индексов K и L (1..N) --------------------- */

int inputIndex(const char *name, int N) {
    double tmp;
    int c;

    while (1) {
        setColorNormal();
        printf("Введите индекс %s (целое от 1 до %d): ", name, N);

        if (scanf("%lf", &tmp) != 1) {
            while ((c = getchar()) != '\n' && c != EOF) {}
            setColorError();
            printf("Ошибка ввода. Введите ЦЕЛОЕ число.\n");
            continue;
        }
        while ((c = getchar()) != '\n' && c != EOF) {}

        if ((int)tmp != tmp) {
            setColorError();
            printf("Ошибка: индекс должен быть целым числом.\n");
            continue;
        }
        int k = (int)tmp;
        if (k < 1 || k > N) {
            setColorError();
            printf("Ошибка: индекс вне диапазона 1..%d.\n", N);
            continue;
        }
        return k;
    }
}

/* --------------------------- Индекс в 1D массиве ------------------------- */

#define IDX(i,j,N) ((i)*(N) + (j))

/* ------------------------- Печать матрицы N x N -------------------------- */

void printMatrix(const int *A, int N) {
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            printf("%5d ", A[IDX(i, j, N)]);
        }
        printf("\n");
    }
}

/* ----------------------------- Обмен столбцов ---------------------------- */

void swapColumns(int *A, int N, int k, int l) {
    for (int i = 0; i < N; ++i) {
        int idx1 = IDX(i, k, N);
        int idx2 = IDX(i, l, N);
        int tmp = A[idx1];
        A[idx1] = A[idx2];
        A[idx2] = tmp;
    }
}

/* --------------------------------- main ---------------------------------- */

int main(void) {
    /* Получаем дескриптор консоли и СРАЗУ сохраняем исходные атрибуты */
    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hConsole, &startInfo);
    defaultAttributes = startInfo.wAttributes;

    /* Включаем UTF‑8, чтобы русский текст нормально отображался */
    SetConsoleOutputCP(65001);
    SetConsoleCP(65001);

    /* Заголовок */
    setColorTitle();
    printf("Лабораторная работа №5. Массивы. Вариант 10.\n");
    setColorNormal();
    printf("Матрица A из N строк и N столбцов размещена в одномерном массиве по строкам.\n");
    printf("Поменять местами K-й и L-й столбцы матрицы. Результат напечатать по строкам.\n\n");

    /* Ввод размерности N (с учётом нецелых значений) */
    const int MAX_N = 1000;
    int N = inputPositiveInt("Введите размер квадратной матрицы N: ", MAX_N);

    /* Выделение памяти под одномерный массив N x N */
    int *A = (int *)malloc(N * N * sizeof(int));
    if (!A) {
        setColorError();
        printf("Ошибка: не удалось выделить память под матрицу.\n");
        SetConsoleTextAttribute(hConsole, defaultAttributes);
        return 1;
    }

    /* Инициализация генератора случайных чисел */
    srand((unsigned int)time(NULL));

    /* Заполнение случайными значениями (например, 0..99) */
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            A[IDX(i, j, N)] = rand() % 100;  // 0..99
        }
    }

    /* Печать исходной матрицы (одним цветом) */
    setColorTitle();
    printf("\nИсходная матрица A:\n");
    setColorNormal();
    printMatrix(A, N);

    /* Ввод индексов K и L (могут вводиться как нецелые, обрабатываем) */
    printf("\n");
    int K = inputIndex("K", N);
    int L = inputIndex("L", N);

    /* Если K и L совпадают, можно просто сообщить, что обмен не нужен */
    if (K == L) {
        setColorError();
        printf("\nПредупреждение: K и L совпадают, обмен столбцов не выполняется.\n");
    } else {
        /* Обмен столбцов (переводим в 0‑базную индексацию) */
        swapColumns(A, N, K - 1, L - 1);
    }

    /* Печать изменённой матрицы (другим цветом заголовка) */
    setColorTitle();
    printf("\nМатрица A после обмена столбцов K = %d и L = %d:\n", K, L);
    setColorNormal();
    printMatrix(A, N);

    /* Освобождаем память */
    free(A);

    /* Возвращаем исходные атрибуты консоли (цвета) */
    SetConsoleTextAttribute(hConsole, defaultAttributes);

    printf("\nНажмите Enter для выхода...");
    getchar(); // на случай, если буфер уже пуст — просто ждём Enter

    return 0;
}