Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## **Часть 1: Исключения**
- ---
- ### **Задача 1: Обработка неправильного формата даты**
- **Описание:** Напишите программу, которая принимает строку в формате "DD/MM/YYYY" и проверяет, является ли она корректной датой (например, 30/02/2023 — некорректно). Если формат неверен или дата невозможна, выбросите исключение.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <string>
- #include <stdexcept>
- #include <sstream>
- void validateDate(const std::string& dateStr) {
- if (dateStr.size() != 10 || dateStr[2] != '/' || dateStr[5] != '/') {
- throw std::invalid_argument("Неверный формат даты. Используйте DD/MM/YYYY.");
- }
- int day, month, year;
- char sep1, sep2;
- std::istringstream iss(dateStr);
- iss >> day >> sep1 >> month >> sep2 >> year;
- if (iss.fail() || day < 1 || day > 31 || month < 1 || month > 12) {
- throw std::invalid_argument("Некорректные значения дня или месяца.");
- }
- // Простая проверка: февраль не может иметь 30 дней
- if (month == 2 && day > 29) {
- throw std::invalid_argument("Февраль не может иметь более 29 дней.");
- }
- std::cout << "Дата корректна: " << dateStr << std::endl;
- }
- int main() {
- std::string input;
- std::cout << "Введите дату в формате DD/MM/YYYY: ";
- std::getline(std::cin, input);
- try {
- validateDate(input);
- } catch (const std::invalid_argument& e) {
- std::cerr << "Ошибка: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 2: Проверка корректности email**
- **Описание:** Напишите функцию, которая проверяет, является ли строка корректным email адресом (должен содержать `@` и точку после `@`). Обработайте некорректный формат.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <string>
- #include <stdexcept>
- void validateEmail(const std::string& email) {
- size_t atPos = email.find('@');
- if (atPos == std::string::npos) {
- throw std::invalid_argument("Email не содержит символ '@'.");
- }
- if (email.find('.', atPos) == std::string::npos) {
- throw std::invalid_argument("Email не содержит доменное имя (точка после '@').");
- }
- std::cout << "Email корректен: " << email << std::endl;
- }
- int main() {
- std::string email;
- std::cout << "Введите email: ";
- std::getline(std::cin, email);
- try {
- validateEmail(email);
- } catch (const std::invalid_argument& e) {
- std::cerr << "Ошибка: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 3: Обработка ошибки при чтении числа из строки**
- **Описание:** Напишите программу, которая читает строку и пытается извлечь из неё **два** числа, разделённых пробелом. Обработайте случаи, когда строка не содержит чисел или содержит лишние символы.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <string>
- #include <sstream>
- #include <stdexcept>
- std::pair<int, int> parseTwoNumbers(const std::string& input) {
- std::istringstream iss(input);
- int a, b;
- char extra;
- if (!(iss >> a >> b) || iss >> extra) {
- throw std::invalid_argument("Ожидается два целых числа, разделённых пробелом.");
- }
- return {a, b};
- }
- int main() {
- std::string input;
- std::cout << "Введите два числа через пробел: ";
- std::getline(std::cin, input);
- try {
- auto [num1, num2] = parseTwoNumbers(input);
- std::cout << "Числа: " << num1 << ", " << num2 << std::endl;
- } catch (const std::invalid_argument& e) {
- std::cerr << "Ошибка: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 4: Обработка ошибки при создании вектора с отрицательным размером**
- **Описание:** Напишите функцию, создающую вектор заданного размера. Обработайте попытку создания вектора с отрицательным размером.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <vector>
- #include <stdexcept>
- std::vector<int> createVector(int size) {
- if (size < 0) {
- throw std::domain_error("Размер вектора не может быть отрицательным.");
- }
- return std::vector<int>(size);
- }
- int main() {
- int size;
- std::cout << "Введите размер вектора: ";
- std::cin >> size;
- try {
- auto vec = createVector(size);
- std::cout << "Вектор успешно создан размером " << vec.size() << std::endl;
- } catch (const std::domain_error& e) {
- std::cerr << "Ошибка: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 5: Исключение при работе с библиотекой (условно)**
- **Описание:** Представьте, что вы работаете с условной "библиотекой" для работы с изображениями. Функция `loadImage` может выбросить исключение, если формат не поддерживается. Имитируйте это поведение.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <string>
- #include <stdexcept>
- void loadImage(const std::string& filename) {
- std::string ext = filename.substr(filename.find_last_of(".") + 1);
- if (ext != "jpg" && ext != "png") {
- throw std::runtime_error("Формат изображения не поддерживается: " + ext);
- }
- std::cout << "Изображение '" << filename << "' загружено." << std::endl;
- }
- int main() {
- std::string file;
- std::cout << "Введите имя файла изображения (jpg/png): ";
- std::getline(std::cin, file);
- try {
- loadImage(file);
- } catch (const std::runtime_error& e) {
- std::cerr << "Ошибка загрузки: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 6: Исключение при попытке доступа к защищённым данным**
- **Описание:** Напишите класс `SecureData`, который имеет приватные данные. Доступ к ним возможен только при предоставлении правильного "ключа". Если ключ неверен, выбросьте исключение.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <stdexcept>
- #include <string>
- class SecureData {
- std::string data = "Секретные данные";
- std::string key = "12345";
- public:
- std::string getData(const std::string& inputKey) {
- if (inputKey != key) {
- throw std::runtime_error("Неверный ключ доступа.");
- }
- return data;
- }
- };
- int main() {
- SecureData sd;
- std::string input;
- std::cout << "Введите ключ: ";
- std::getline(std::cin, input);
- try {
- std::cout << "Данные: " << sd.getData(input) << std::endl;
- } catch (const std::runtime_error& e) {
- std::cerr << "Ошибка: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 7: Обработка ошибки при конвертации валюты**
- **Описание:** Напишите функцию `convertCurrency`, которая принимает сумму и код валюты. Если код валюты неизвестен, выбросьте исключение.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <stdexcept>
- #include <string>
- double convertCurrency(double amount, const std::string& currency) {
- if (currency == "USD") return amount * 1.0;
- if (currency == "EUR") return amount * 0.85;
- if (currency == "RUB") return amount * 90.0;
- throw std::invalid_argument("Неизвестный код валюты: " + currency);
- }
- int main() {
- double amount;
- std::string currency;
- std::cout << "Введите сумму: ";
- std::cin >> amount;
- std::cout << "Введите код валюты (USD, EUR, RUB): ";
- std::cin >> currency;
- try {
- double result = convertCurrency(amount, currency);
- std::cout << "Результат: " << result << " USD" << std::endl;
- } catch (const std::invalid_argument& e) {
- std::cerr << "Ошибка: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 8: Исключение при работе с базой данных (условно)**
- **Описание:** Имитируйте подключение к базе данных. Если строка подключения некорректна (например, отсутствует хост), выбросьте исключение.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <string>
- #include <stdexcept>
- void connectToDatabase(const std::string& connStr) {
- if (connStr.find("host=") == std::string::npos) {
- throw std::runtime_error("Строка подключения не содержит 'host'.");
- }
- std::cout << "Подключение к базе данных установлено." << std::endl;
- }
- int main() {
- std::string conn;
- std::cout << "Введите строку подключения (например, host=localhost): ";
- std::getline(std::cin, conn);
- try {
- connectToDatabase(conn);
- } catch (const std::runtime_error& e) {
- std::cerr << "Ошибка подключения: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 9: Обработка ошибки при вычислении факториала**
- **Описание:** Напишите функцию `factorial`, которая вычисляет факториал числа. Обработайте отрицательные числа и числа, превышающие разумный предел (например, 20).
- **Решение:**
- ```cpp
- #include <iostream>
- #include <stdexcept>
- long long factorial(int n) {
- if (n < 0) {
- throw std::domain_error("Факториал отрицательного числа не определён.");
- }
- if (n > 20) {
- throw std::overflow_error("Факториал числа слишком велик для вычисления.");
- }
- long long result = 1;
- for (int i = 2; i <= n; ++i) {
- result *= i;
- }
- return result;
- }
- int main() {
- int num;
- std::cout << "Введите число для вычисления факториала: ";
- std::cin >> num;
- try {
- long long result = factorial(num);
- std::cout << "Факториал " << num << " = " << result << std::endl;
- } catch (const std::domain_error& e) {
- std::cerr << "Ошибка: " << e.what() << std::endl;
- } catch (const std::overflow_error& e) {
- std::cerr << "Ошибка: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ### **Задача 10: Обработка исключения при логировании**
- **Описание:** Напишите простую функцию логирования в файл. Если файл не удаётся открыть, выбросьте исключение.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <fstream>
- #include <stdexcept>
- #include <string>
- void logToFile(const std::string& message, const std::string& filename) {
- std::ofstream file(filename, std::ios::app);
- if (!file.is_open()) {
- throw std::runtime_error("Не удалось открыть файл для логирования: " + filename);
- }
- file << message << std::endl;
- file.close();
- std::cout << "Сообщение записано в лог." << std::endl;
- }
- int main() {
- std::string msg, file;
- std::cout << "Введите сообщение для лога: ";
- std::getline(std::cin, msg);
- std::cout << "Введите имя файла лога: ";
- std::getline(std::cin, file);
- try {
- logToFile(msg, file);
- } catch (const std::runtime_error& e) {
- std::cerr << "Ошибка логирования: " << e.what() << std::endl;
- }
- return 0;
- }
- ```
- ---
- ## **Часть 2: Пространство имён**
- ---
- ### **Задача 1: Организация функций ввода-вывода**
- **Описание:** Создайте пространство имён `IO` с функциями `readInt()` и `writeInt()`, которые обертывают `std::cin` и `std::cout`.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace IO {
- int readInt() {
- int val;
- std::cin >> val;
- return val;
- }
- void writeInt(int val) {
- std::cout << val << std::endl;
- }
- }
- int main() {
- std::cout << "Введите число: ";
- int num = IO::readInt();
- std::cout << "Вы ввели: ";
- IO::writeInt(num);
- return 0;
- }
- ```
- ---
- ### **Задача 2: Пространство имён для констант физических величин**
- **Описание:** Создайте пространство имён `Physics` с константами, такими как `SPEED_OF_LIGHT`, `GRAVITY`.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace Physics {
- const double SPEED_OF_LIGHT = 299792458.0; // м/с
- const double GRAVITY = 9.81; // м/с^2
- }
- int main() {
- std::cout << "Скорость света: " << Physics::SPEED_OF_LIGHT << " м/с" << std::endl;
- std::cout << "Ускорение свободного падения: " << Physics::GRAVITY << " м/с^2" << std::endl;
- return 0;
- }
- ```
- ---
- ### **Задача 3: Пространство имён для математических функций**
- **Описание:** Создайте пространство имён `MathUtils` с функцией `power`, которая возводит число в степень.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace MathUtils {
- double power(double base, int exp) {
- double result = 1.0;
- for (int i = 0; i < exp; ++i) {
- result *= base;
- }
- return result;
- }
- }
- int main() {
- double base = 2.0;
- int exp = 3;
- std::cout << base << "^" << exp << " = " << MathUtils::power(base, exp) << std::endl;
- return 0;
- }
- ```
- ---
- ### **Задача 4: Использование `using` для сокращения кода**
- **Описание:** В `main` используйте `using` для импорта конкретной функции из пространства `MathUtils` и вызовите её.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace MathUtils {
- double power(double base, int exp) {
- double result = 1.0;
- for (int i = 0; i < exp; ++i) {
- result *= base;
- }
- return result;
- }
- }
- int main() {
- using MathUtils::power;
- std::cout << "2^4 = " << power(2, 4) << std::endl;
- return 0;
- }
- ```
- ---
- ### **Задача 5: Пространство имён для работы с геометрией**
- **Описание:** Создайте пространство имён `Shapes` с классом `Rectangle`, который имеет метод `area`.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace Shapes {
- class Rectangle {
- double width, height;
- public:
- Rectangle(double w, double h) : width(w), height(h) {}
- double area() const {
- return width * height;
- }
- };
- }
- int main() {
- Shapes::Rectangle rect(5.0, 3.0);
- std::cout << "Площадь прямоугольника: " << rect.area() << std::endl;
- return 0;
- }
- ```
- ---
- ### **Задача 6: Вложенные пространства имён для библиотеки**
- **Описание:** Создайте вложенное пространство имён `Graphics::2D` с функцией `drawLine`.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace Graphics {
- namespace _2D {
- void drawLine(int x1, int y1, int x2, int y2) {
- std::cout << "Рисуем линию от (" << x1 << "," << y1 << ") до (" << x2 << "," << y2 << ")" << std::endl;
- }
- }
- }
- int main() {
- Graphics::_2D::drawLine(0, 0, 10, 10);
- return 0;
- }
- ```
- ---
- ### **Задача 7: Повторное объявление пространства имён с классом и функцией**
- **Описание:** Объявите пространство `Game` дважды: в первом — класс `Player`, во втором — функцию `resetGame`.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace Game {
- class Player {
- public:
- std::string name;
- Player(const std::string& n) : name(n) {}
- };
- }
- namespace Game {
- void resetGame() {
- std::cout << "Игра сброшена." << std::endl;
- }
- }
- int main() {
- Game::Player p("Alice");
- std::cout << "Игрок: " << p.name << std::endl;
- Game::resetGame();
- return 0;
- }
- ```
- ---
- ### **Задача 8: Пространство имён для настроек приложения**
- **Описание:** Создайте пространство имён `AppConfig` с переменными `windowWidth`, `windowHeight`.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace AppConfig {
- int windowWidth = 800;
- int windowHeight = 600;
- }
- int main() {
- std::cout << "Размер окна: " << AppConfig::windowWidth << "x" << AppConfig::windowHeight << std::endl;
- return 0;
- }
- ```
- ---
- ### **Задача 9: Пространство имён для вспомогательных утилит**
- **Описание:** Создайте пространство `Utils` с функцией `trim`, которая удаляет пробелы в начале и в конце строки.
- **Решение:**
- ```cpp
- #include <iostream>
- #include <string>
- namespace Utils {
- std::string trim(const std::string& str) {
- size_t start = str.find_first_not_of(" \t\n\r");
- if (start == std::string::npos) return "";
- size_t end = str.find_last_not_of(" \t\n\r");
- return str.substr(start, end - start + 1);
- }
- }
- int main() {
- std::string input = " hello world ";
- std::cout << "До: [" << input << "]" << std::endl;
- std::cout << "После: [" << Utils::trim(input) << "]" << std::endl;
- return 0;
- }
- ```
- ---
- ### **Задача 10: Анонимное пространство имён для локальной утилиты**
- **Описание:** Создайте анонимное пространство имён с функцией `isEven`, которая используется только внутри текущего файла.
- **Решение:**
- ```cpp
- #include <iostream>
- namespace {
- bool isEven(int n) {
- return n % 2 == 0;
- }
- }
- int main() {
- int num = 42;
- if (isEven(num)) {
- std::cout << num << " - чётное." << std::endl;
- } else {
- std::cout << num << " - нечётное." << std::endl;
- }
- return 0;
- }
- ```
- ---
- Эти задачи показывают, как исключения и пространства имён применяются на практике для повышения надёжности, читаемости и структурированности кода.
Advertisement
Add Comment
Please, Sign In to add comment