Загрузка данных
#define _CRT_SECURE_NO_WARNINGS
#include "Header.h"
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ==========
void SetCursorPosition(short row, short col) {
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD position = { col, row };
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";
}
void SetColor(int text, int bg) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (bg << 4) | text);
}
// Вспомогательная функция для вывода double с запятой вместо точки
void PrintDouble(double val) {
string s = to_string(val);
// Убираем лишние нули на конце
s.erase(s.find_last_not_of('0') + 1, string::npos);
if (s.back() == '.') s.pop_back();
// Заменяем точку на запятую
for (char& c : s) if (c == '.') c = ',';
cout << s;
}
// ========== ФУНКЦИИ ВВОДА С ESC ==========
bool ReadStringWithESC(string& out) {
out.clear();
while (true) {
if (_kbhit()) {
int ch = _getch();
if (ch == 27) {
cout << "\n\n[ESC] Возврат в меню...\n";
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) (void)_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;
bool valid = true;
size_t start = 0;
if (s[0] == '-') {
if (s.length() == 1) valid = false;
else start = 1;
}
for (size_t i = start; i < s.length(); i++) {
if (!isdigit(static_cast<unsigned char>(s[i]))) {
valid = false;
break;
}
}
if (!valid) {
if (!errorShown) {
cout << endl;
errorPos = GetCursorPosition();
errorShown = true;
}
SetCursorPosition(errorPos.Y, errorPos.X);
SPACEBACK(50);
cout << "Ошибка! Введите целое число: ";
s.clear();
continue;
}
try {
val = stoi(s);
return true;
}
catch (...) {
if (!errorShown) {
cout << endl;
errorPos = GetCursorPosition();
errorShown = true;
}
SetCursorPosition(errorPos.Y, errorPos.X);
SPACEBACK(50);
cout << "Ошибка! Введите целое число: ";
s.clear();
}
}
}
bool ReadDoubleWithESC(double& val) {
std::string s;
COORD errorPos = { 0, 0 };
bool errorShown = false;
while (true) {
if (!ReadStringWithESC(s)) return false;
if (s.empty()) continue;
try {
for (char& c : s) if (c == '.') c = ',';
size_t pos = 0;
val = std::stod(s, &pos);
if (pos != s.length()) throw std::invalid_argument("Trailing characters");
return true;
}
catch (...) {
if (!errorShown) {
cout << endl;
errorPos = GetCursorPosition();
errorShown = true;
}
SetCursorPosition(errorPos.Y, errorPos.X);
SPACEBACK(50);
cout << "Ошибка! Введите число: ";
s.clear();
}
}
}
// ========== ЛАБОРАТОРНАЯ РАБОТА 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 << " Допускается ввод чисел с плавающей точкой и в научном формате (например, 1e5).\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Введённые числа: ";
for (int i = 0; i < SIZE; i++) {
PrintDouble(arr[i]);
cout << " ";
}
cout << 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";
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Введённые числа: ";
for (int i = 0; i < N; i++) {
PrintDouble(arr[i]);
cout << " ";
}
cout << 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";
cout << " отрицательного элемента и номер последнего отрицательного.\n";
cout << " Допустимы целые, вещественные числа и научная нотация.\n";
cout << "===============================================================================\n\n";
SetColor(7, 0);
string path;
cout << "Введите название файла (например, data.txt). Для выхода введите \"*\": ";
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
getline(cin, path);
if (path == "*") return 0;
ifstream fs(path);
if (!fs.is_open()) {
cout << "\nОшибка открытия файла \"" << path << "\"\n";
cerr << "Детали ошибки: " << strerror(errno) << " (код " << errno << ")" << endl;
system("pause");
return 1;
}
cout << "Файл открыт.\n\n";
string token;
int count = 0;
streampos errorPos = 0;
bool error = false;
string badToken;
while (fs >> token) {
count++;
size_t pos = 0;
string tmp = token;
replace(tmp.begin(), tmp.end(), '.', ',');
try {
stod(tmp, &pos);
if (pos != tmp.length()) throw invalid_argument("garbage");
}
catch (...) {
errorPos = fs.tellg();
if (errorPos >= static_cast<streamoff>(token.length()))
errorPos -= token.length();
else
errorPos = 0;
badToken = token;
error = true;
break;
}
}
if (count == 0 && !error) {
cout << "Файл пуст.\n";
system("pause");
return 1;
}
if (error) {
cout << "Ошибка: некорректные данные в файле.\n";
cout << "Номер элемента с ошибкой: " << count << endl;
cout << "Позиция ошибки (байт): " << static_cast<int>(errorPos) << endl;
cout << "Ошибочная лексема: \"" << badToken << "\"\n";
system("pause");
return 1;
}
if (count != 15) {
cout << "Внимание: в файле " << count << " элементов (ожидалось 15).\n";
}
double* arr = new (nothrow) double[count];
if (!arr) {
cout << "Ошибка выделения памяти.\n";
system("pause");
return 1;
}
fs.close();
fs.open(path);
for (int i = 0; i < count; i++) {
fs >> token;
replace(token.begin(), token.end(), '.', ',');
arr[i] = stod(token);
}
fs.close();
cout << "\nПрочитанные числа:\n";
for (int i = 0; i < count; i++) {
cout << "x[" << i + 1 << "] = ";
PrintDouble(arr[i]);
cout << endl;
}
int firstNeg = -1, lastNeg = -1;
for (int i = 0; i < count; 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;
}
delete[] arr;
cout << "\nНажмите любую клавишу...";
(void)_getch();
return 0;
}
// ========== ЛАБИРИНТ ==========
int Labirint() {
system("cls");
info();
SetColor(11, 0);
cout << "===============================================================================\n";
cout << "Игра: Лабиринт 32x32\n";
cout << "===============================================================================\n";
SetColor(7, 0);
cout << "Задача: Пройти лабиринт от старта (верхний левый угол) до выхода (отмечен 'ВХ').\n";
cout << " Стены отображаются чёрным цветом, проходы - белым.\n";
cout << " Игрок (жук) отображается красным квадратом.\n";
cout << "===============================================================================\n";
cout << "Управление:\n";
cout << " Стрелки - движение по лабиринту.\n";
cout << " F5 - показать/скрыть кратчайший путь до выхода (зелёный цвет).\n";
cout << "===============================================================================\n\n";
SetColor(7, 0);
unsigned int map[32] = {
0b10111111111111111111111111111111,
0b10000000000000000000000000000001,
0b10111111111111111111111111111101,
0b10000000100000000000001000000001,
0b10111110101111111111110101111101,
0b10000010100000000000000101000001,
0b10111010101110111011101010111011,
0b10001000100010001000100010001001,
0b11101011111011101110111110101111,
0b10001000001000100010000000100001,
0b10111011101110111011101110111011,
0b10000010000000100000000001000001,
0b11111110111111101111111101111111,
0b10000000100000000000001000000001,
0b10111111101111111111110111111101,
0b10000000001000000000000000000001,
0b11101111111011101110111111101111,
0b10001000001000100010000000100001,
0b10111011101110111011101110111011,
0b10000010000000100000000001000001,
0b11111110111111101111111101111111,
0b10000000100000000000001000000001,
0b10111111101111111111110111111101,
0b10000000001000000000000000000001,
0b11101111111011101110111111101111,
0b10001000001000100010000000100001,
0b10111011101110111011101110111011,
0b10000010000000100000000001000001,
0b11111110111111101111111101111111,
0b10000000100000000000001000000011,
0b10111111111111111111111111111111,
0b10111111111111111111111111111111
};
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
const int WHITE = 15 << 4;
const int BLACK = 0;
const int RED = BACKGROUND_RED | BACKGROUND_INTENSITY;
const int GREEN = BACKGROUND_GREEN | BACKGROUND_INTENSITY;
int bugR = 0, bugC = 1;
int exitR = 31, exitC = 1;
auto isWall = [&](int r, int c) { return (map[r] >> (31 - c)) & 1; };
if (isWall(exitR, exitC)) { exitR = 31; exitC = 30; }
COORD topLeft;
unsigned int path[32] = { 0 };
bool pathShown = false;
bool gameOver = false;
bool wasActive = true;
auto redraw = [&]() {
topLeft = GetCursorPosition();
for (int r = 0; r < 32; r++) {
for (int c = 0; c < 32; c++) {
SetConsoleTextAttribute(h, isWall(r, c) ? BLACK : WHITE);
cout << " ";
}
cout << endl;
}
SetCursorPosition(topLeft.Y + exitR, topLeft.X + exitC * 2);
SetConsoleTextAttribute(h, WHITE | 10);
cout << "ВХ";
SetConsoleTextAttribute(h, 7);
if (pathShown) {
for (int r = 0; r < 32; r++) {
for (int c = 0; c < 32; c++) {
if (path[r] & (1 << (31 - c))) {
SetConsoleTextAttribute(h, GREEN);
SetCursorPosition(topLeft.Y + r, topLeft.X + c * 2);
cout << " ";
}
}
}
}
SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
SetConsoleTextAttribute(h, RED);
cout << " ";
SetConsoleTextAttribute(h, 7);
};
topLeft = GetCursorPosition();
for (int r = 0; r < 32; r++) {
for (int c = 0; c < 32; c++) {
SetConsoleTextAttribute(h, isWall(r, c) ? BLACK : WHITE);
cout << " ";
}
cout << endl;
}
SetCursorPosition(topLeft.Y + exitR, topLeft.X + exitC * 2);
SetConsoleTextAttribute(h, WHITE | 10);
cout << "ВХ";
SetConsoleTextAttribute(h, 7);
SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
SetConsoleTextAttribute(h, RED);
cout << " ";
SetConsoleTextAttribute(h, 7);
while (!gameOver) {
if (GetConsoleWindow() != GetForegroundWindow()) {
wasActive = false;
Sleep(100);
continue;
}
if (!wasActive && GetConsoleWindow() == GetForegroundWindow()) {
redraw();
wasActive = true;
}
if (!_kbhit()) {
Sleep(10);
continue;
}
unsigned char key = _getch();
if (key == 27) return 0;
if (key == 0) {
key = _getch();
if (key == 63) {
if (!pathShown) {
memset(path, 0, sizeof(path));
int visited[32][32] = { 0 };
int prevR[32][32], prevC[32][32];
for (int i = 0; i < 32; i++)
for (int j = 0; j < 32; j++)
prevR[i][j] = prevC[i][j] = -1;
queue<pair<int, int>> q;
q.push({ bugR, bugC });
visited[bugR][bugC] = 1;
bool found = false;
while (!q.empty() && !found) {
pair<int, int> cur = q.front(); q.pop();
int r = cur.first, c = cur.second;
int dr[] = { 1,0,-1,0 }, dc[] = { 0,1,0,-1 };
for (int i = 0; i < 4; i++) {
int nr = r + dr[i], nc = c + dc[i];
if (nr >= 0 && nr < 32 && nc >= 0 && nc < 32 && !isWall(nr, nc) && !visited[nr][nc]) {
visited[nr][nc] = 1;
prevR[nr][nc] = r;
prevC[nr][nc] = c;
if (nr == exitR && nc == exitC) { found = true; break; }
q.push({ nr, nc });
}
}
}
if (found) {
int r = exitR, c = exitC;
while (!(r == bugR && c == bugC)) {
path[r] |= 1 << (31 - c);
SetConsoleTextAttribute(h, GREEN);
SetCursorPosition(topLeft.Y + r, topLeft.X + c * 2);
cout << " ";
int pr = prevR[r][c], pc = prevC[r][c];
r = pr; c = pc;
}
path[bugR] |= 1 << (31 - bugC);
SetConsoleTextAttribute(h, GREEN);
SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
cout << " ";
}
SetConsoleTextAttribute(h, RED);
SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
cout << " ";
SetConsoleTextAttribute(h, 7);
SetCursorPosition(topLeft.Y + 33, 0);
SetConsoleTextAttribute(h, BLACK | 14);
cout << (found ? "ПУТЬ НАЙДЕН! " : "ПУТИ НЕТ. ");
SetConsoleTextAttribute(h, 7);
pathShown = found;
}
else {
for (int r = 0; r < 32; r++)
for (int c = 0; c < 32; c++)
if (path[r] & (1 << (31 - c))) {
SetConsoleTextAttribute(h, WHITE);
SetCursorPosition(topLeft.Y + r, topLeft.X + c * 2);
cout << " ";
}
memset(path, 0, sizeof(path));
pathShown = false;
SetConsoleTextAttribute(h, RED);
SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
cout << " ";
SetConsoleTextAttribute(h, 7);
}
continue;
}
}
if (key == 224) {
key = _getch();
int newR = bugR, newC = bugC;
switch (key) {
case 75: newC--; break;
case 77: newC++; break;
case 72: newR--; break;
case 80: newR++; break;
default: continue;
}
if (newR < 0 || newR >= 32 || newC < 0 || newC >= 32 || isWall(newR, newC)) {
Beep(750, 300);
continue;
}
SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
if (pathShown && (path[bugR] & (1 << (31 - bugC))))
SetConsoleTextAttribute(h, GREEN);
else
SetConsoleTextAttribute(h, WHITE);
cout << " ";
bugR = newR; bugC = newC;
SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
SetConsoleTextAttribute(h, RED);
cout << " ";
if (bugR == exitR && bugC == exitC) {
SetConsoleTextAttribute(h, BLACK | 14);
SetCursorPosition(topLeft.Y + 33, 0);
cout << "ПОЗДРАВЛЯЕМ! ВЫ ВЫШЛИ!";
Beep(1000, 500);
gameOver = true;
}
SetConsoleTextAttribute(h, 7);
}
}
cout << "\n\nНажмите любую клавишу для возврата в меню...";
(void)_getch();
return 0;
}
// ========== МАСКА ==========
int MASKA() {
system("cls");
info();
SetColor(11, 0);
cout << "===============================================================================\n";
cout << "Задание: Маска\n";
cout << "===============================================================================\n";
SetColor(7, 0);
cout << "Задача: Задан массив y[1], y[2], ..., y[20].\n";
cout << " Определить, какие значения массива соответствуют маске (01010100).\n";
cout << "===============================================================================\n\n";
SetColor(7, 0);
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<int> dist(600, 3000);
int mas[20];
unsigned short maska = 0x54;
cout << "Сгенерированные числа:\n";
for (int i = 0; i < 20; i++) {
mas[i] = dist(gen);
cout << "y[" << i + 1 << "] = " << setw(4) << mas[i];
if ((i + 1) % 5 == 0) cout << endl;
else cout << " ";
}
cout << "\n\nЧисла, соответствующие маске 0x54 (01010100):\n";
cout << "------------------------------------------------------------------------------\n";
bool found = false;
for (int i = 0; i < 20; i++) {
if ((mas[i] & maska) == maska) {
cout << "y[" << i + 1 << "] = " << mas[i]
<< " (dec), 0x" << hex << mas[i] << dec << " (hex), ob"
<< bitset<16>(mas[i]) << " (bin)" << endl;
found = true;
}
}
if (!found) cout << "Нет чисел, соответствующих маске 0x54.\n";
cout << "\nНажмите любую клавишу...";
(void)_getch();
return 0;
}
// ========== МАКРОСЫ ==========
int Macros() {
system("cls");
info();
ENDL;
cout << "В данном задании представлено использование макросов, выделяющих старшие и младшие биты числа, а также меняющих старшие и младшие биты местами. Ниже представлены четыре переменные с разными размерами. Их значения даны через \"/\" (сначала значение в десятичной системе счисления, потом в шестнадцатеричной). После этого идет размер переменной и использование на ней макросов:" << endl;
ENDL;
const unsigned char B = 230;
const unsigned short Sh = 15678;
const unsigned int I = 564872844;
const unsigned long long LL = 9903331736939477691ULL;
ENDL;
cout << "byte: " << dec << static_cast<int>(B) << " / " << hex << static_cast<int>(B) << endl;
cout << "--"; cout << "Размер byte: " << sizeof(B) << "байт" << endl;
cout << "Старшие биты: " << hex << Hi(B) << "\n";
cout << "Младшие биты: " << hex << Lo(B) << "\n";
cout << "Старшие и младшие биты, поменянные местами: " << hex << Swap(B) << endl;
ENDL;
cout << "short: " << dec << Sh << " / " << hex << Sh << endl;
cout << "--"; cout << "Размер short: " << sizeof(Sh) << "байта" << endl;
cout << "Старшие биты: " << hex << Hi(Sh) << "\n";
cout << "Младшие биты: " << hex << Lo(Sh) << "\n";
cout << "Старшие и младшие биты, поменянные местами: " << hex << Swap(Sh) << endl;
ENDL;
cout << "integer: " << dec << I << " / " << hex << I << endl;
cout << "--"; cout << "Размер integer: " << sizeof(I) << "байта" << endl;
cout << "Старшие биты: " << hex << Hi(I) << "\n";
cout << "Младшие биты: " << hex << Lo(I) << "\n";
cout << "Старшие и младшие биты, поменянные местами: " << hex << Swap(I) << endl;
ENDL;
cout << "long long: " << dec << LL << " / " << hex << LL << endl;
cout << "--"; cout << "Размер long long: " << sizeof(LL) << "байт" << endl;
cout << "Старшие биты: " << hex << Hi(LL) << "\n";
cout << "Младшие биты: " << hex << Lo(LL) << "\n";
cout << "Старшие и младшие биты, поменянные местами: " << hex << Swap(LL) << endl;
ENDL;
system("pause");
return 0;
}
// ========== ШИФРОВАНИЕ ==========
static void Incryption_byte(int len, unsigned char ch, char* txt) {
unsigned char* p = reinterpret_cast<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);
SetColor(10, 0);
cout << "\n[ГОТОВО] Текст зашифрован побитовым сдвигом.\n";
SetColor(7, 0);
cout << "Нажмите любую клавишу...";
(void)_getch();
}
static void Decryption_byte(int len, unsigned char& ch, char* txt) {
unsigned char* p = reinterpret_cast<unsigned char*>(txt);
ch = p[len - 1] & 0x01;
for (int i = len - 1; i >= 0; i--) {
p[i] &= 0xFE;
p[i] >>= 1;
if (i > 0) {
p[i] |= (p[i - 1] & 0x01) << 7;
}
}
p[0] |= ch << 7;
SetColor(10, 0);
cout << "\n[ГОТОВО] Текст расшифрован побитовым сдвигом.\n";
SetColor(7, 0);
cout << "Нажмите любую клавишу...";
(void)_getch();
}
static void Dynamic_Encrypt(int len, unsigned char ch, char* txt) {
unsigned char* p = reinterpret_cast<unsigned char*>(txt);
for (int i = 0; i < len; i++) {
p[i] = (p[i] + i) % 256;
}
SetColor(10, 0);
cout << "\n[ГОТОВО] Текст зашифрован динамическим сдвигом.\n";
SetColor(7, 0);
cout << "Нажмите любую клавишу...";
(void)_getch();
}
static void Dynamic_Decrypt(int len, unsigned char ch, char* txt) {
unsigned char* p = reinterpret_cast<unsigned char*>(txt);
for (int i = 0; i < len; i++) {
p[i] = (p[i] - i + 256) % 256;
}
SetColor(10, 0);
cout << "\n[ГОТОВО] Текст расшифрован динамическим сдвигом.\n";
SetColor(7, 0);
cout << "Нажмите любую клавишу...";
(void)_getch();
}
static bool Caesar_Encrypt(int len, unsigned char ch, char* txt, int N) {
if (N == 0) {
cout << "\nСдвиг равен 0, текст не изменился.\n";
return false;
}
const char* en_up = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char* en_lo = "abcdefghijklmnopqrstuvwxyz";
const char* ru_up = "\xC0\xC1\xC2\xC3\xC4\xC5\xA8\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF";
const char* ru_lo = "\xE0\xE1\xE2\xE3\xE4\xE5\xB8\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
for (int i = 0; i < len; i++) {
unsigned char c = static_cast<unsigned char>(txt[i]);
const char* alpha = nullptr;
int size = 0;
const char* pos = nullptr;
if ((pos = strchr(en_up, c))) { alpha = en_up; size = 26; }
else if ((pos = strchr(en_lo, c))) { alpha = en_lo; size = 26; }
else if ((pos = strchr(ru_up, c))) { alpha = ru_up; size = 33; }
else if ((pos = strchr(ru_lo, c))) { alpha = ru_lo; size = 33; }
else continue;
int idx = static_cast<int>(pos - alpha);
int normN = ((N % size) + size) % size;
txt[i] = alpha[(idx + normN) % size];
}
SetColor(10, 0);
cout << "\n[ГОТОВО] Текст зашифрован методом Цезаря (сдвиг " << N << ").\n";
SetColor(7, 0);
cout << "Нажмите любую клавишу...";
(void)_getch();
return true;
}
static bool Caesar_Decrypt(int len, unsigned char ch, char* txt, int N) {
if (N == 0) {
cout << "\nСдвиг равен 0, текст не изменился.\n";
return false;
}
const char* en_up = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char* en_lo = "abcdefghijklmnopqrstuvwxyz";
const char* ru_up = "\xC0\xC1\xC2\xC3\xC4\xC5\xA8\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF";
const char* ru_lo = "\xE0\xE1\xE2\xE3\xE4\xE5\xB8\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
for (int i = 0; i < len; i++) {
unsigned char c = static_cast<unsigned char>(txt[i]);
const char* alpha = nullptr;
int size = 0;
const char* pos = nullptr;
if ((pos = strchr(en_up, c))) { alpha = en_up; size = 26; }
else if ((pos = strchr(en_lo, c))) { alpha = en_lo; size = 26; }
else if ((pos = strchr(ru_up, c))) { alpha = ru_up; size = 33; }
else if ((pos = strchr(ru_lo, c))) { alpha = ru_lo; size = 33; }
else continue;
int idx = static_cast<int>(pos - alpha);
int normN = ((N % size) + size) % size;
txt[i] = alpha[(idx - normN + size) % size];
}
SetColor(10, 0);
cout << "\n[ГОТОВО] Текст расшифрован методом Цезаря (сдвиг " << N << ").\n";
SetColor(7, 0);
cout << "Нажмите любую клавишу...";
(void)_getch();
return true;
}
int CIPHER() {
system("cls");
info();
SetColor(11, 0);
cout << "=================== ШИФРОВАНИЕ ТЕКСТА ===================\n";
SetColor(7, 0);
cout << "Методы: Цезарь, побитовый сдвиг, динамический сдвиг.\n\n";
string input;
cout << "Введите текст (не более 24 символов): ";
if (!ReadStringWithESC(input)) return 0;
int len = static_cast<int>(input.length());
if (len == 0) {
cout << "Текст пуст!\n";
system("pause");
return 1;
}
if (len > 24) {
cout << "Текст слишком длинный, обрезаем до 24 символов.\n";
input = input.substr(0, 24);
len = 24;
}
char* txt = new char[len + 1];
memcpy(txt, input.c_str(), len + 1);
unsigned char ch = static_cast<unsigned char>(txt[0]) & 0x80;
char choice;
do {
system("cls");
SetColor(15, 0);
cout << "========== ТЕКУЩИЙ ТЕКСТ ==========\n";
SetColor(7, 0);
for (int i = 0; i < len; i++) {
cout << bitset<8>(static_cast<unsigned char>(txt[i])) << " ";
}
cout << "\n";
SetColor(14, 0);
cout << "Текст: " << txt << "\n";
SetColor(7, 0);
cout << "===================================\n\n";
SetColor(11, 0); cout << "1. Шифр Цезаря\n";
SetColor(10, 0); cout << "2. Дешифр Цезаря\n";
SetColor(11, 0); cout << "3. Побитовый шифр\n";
SetColor(10, 0); cout << "4. Побитовый дешифр\n";
SetColor(11, 0); cout << "5. Динамический шифр\n";
SetColor(10, 0); cout << "6. Динамический дешифр\n";
SetColor(12, 0); cout << "0. Выход в меню\n";
SetColor(7, 0);
cout << "-----------------------------------\n";
cout << "Выберите действие: ";
choice = _getch();
cout << choice << endl;
switch (choice) {
case '1': {
int key;
cout << "Введите ключ (сдвиг): ";
if (ReadIntWithESC(key))
Caesar_Encrypt(len, ch, txt, key);
break;
}
case '2': {
int key;
cout << "Введите ключ (сдвиг): ";
if (ReadIntWithESC(key))
Caesar_Decrypt(len, ch, txt, key);
break;
}
case '3':
Incryption_byte(len, ch, txt);
break;
case '4':
Decryption_byte(len, ch, txt);
break;
case '5':
Dynamic_Encrypt(len, ch, txt);
break;
case '6':
Dynamic_Decrypt(len, ch, txt);
break;
case '0': break;
default:
SetColor(12, 0);
cout << "\nНеверный выбор. Нажмите любую клавишу...";
SetColor(7, 0);
(void)_getch();
}
} while (choice != '0' && choice != 27);
delete[] txt;
return 0;
}
// ========== ГЛАВНОЕ МЕНЮ ==========
int main() {
SetConsoleTitle(L"Лабораторная работа");
setlocale(LC_ALL, "rus");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
srand(static_cast<unsigned>(time(NULL)));
ios::sync_with_stdio(false);
cin.tie(nullptr);
unsigned char ch = 0;
do {
system("cls");
info();
SetColor(11, 0);
cout << "===============================================================================\n";
cout << " МЕНЮ ПРОГРАММЫ \n";
cout << "===============================================================================\n";
SetColor(7, 0);
cout << " 1 - Лабораторная работа №1 (Массив x1..x15)\n";
cout << " 2 - Лабораторная работа №2 (Массив x1..xN)\n";
cout << " 3 - Лабораторная работа №3 (Файловый ввод)\n";
cout << " 4 - Игра: Лабиринт 32x32\n";
cout << " 5 - Задание: Маска (числа 600..3000, поиск по 0x54)\n";
cout << " 6 - Задание: Макросы Hi, Lo, Swap\n";
cout << " 7 - Задание: Шифрование (3 метода)\n";
SetColor(12, 0);
cout << " ESC - выход из программы\n";
SetColor(7, 0);
cout << "===============================================================================\n";
cout << "Выберите пункт: ";
ch = _getch();
cout << ch << endl;
switch (ch) {
case '1': Lab1_Static(); break;
case '2': Lab2_Dynamic(); break;
case '3': Lab3_File(); break;
case '4': Labirint(); break;
case '5': MASKA(); break;
case '6': Macros(); break;
case '7': CIPHER(); break;
case 27: break;
default: SetColor(12, 0); cout << "Неверный выбор! Нажмите любую клавишу...\n"; SetColor(7, 0); (void)_getch(); break;
}
} while (ch != 27);
return 0;
}