Menu
CoddyTech

Bộ xử lý bắt mọi ngoại lệ

Thuộc phần Logic và luồng chương trình trong hành trình C++ của Coddy. Bài học 52 trên 56.

Đôi khi chương trình có thể gặp lỗi bất ngờ không thuộc các kiểu ngoại lệ cụ thể mà bạn đã dự liệu. Trình xử lý tổng quát catch(...) tạo một lớp bảo vệ, bắt mọi ngoại lệ mà các khối catch cụ thể hơn chưa xử lý.

Bộ xử lý bắt mọi ngoại lệ dùng ba dấu chấm (...) thay vì chỉ định một kiểu ngoại lệ cụ thể. Bạn phải đặt nó sau tất cả các khối catch khác vì C++ kiểm tra chúng theo thứ tự:

try {
    // Đoạn code có thể phát sinh nhiều loại ngoại lệ (exception)
} catch (std::invalid_argument& e) {
    std::cout << "Invalid input!" << std::endl;
} catch (std::out_of_range& e) {
    std::cout << "Number too large!" << std::endl;
} catch (...) {
    std::cout << "An unexpected error occurred!" << std::endl;
}

Trình xử lý tổng quát đóng vai trò dự phòng cho mọi loại ngoại lệ mà các khối lệnh trước đó chưa bắt. Cách này đặc biệt hữu ích khi bạn làm việc với code có thể phát sinh những ngoại lệ bạn không lường trước, giúp chương trình không bị sập do lỗi bất ngờ.

Dù không thể truy cập thông tin cụ thể về ngoại lệ trong khối bắt tất cả, bạn vẫn có thể đưa ra thông báo lỗi chung và thực hiện các thao tác dọn dẹp để chương trình tiếp tục chạy ổn định.

challenge icon

Thử thách

Dễ

Tạo một chương trình minh họa cách xử lý ngoại lệ toàn diện bằng nhiều khối catch, bao gồm cả trình xử lý bắt tất cả. Thử thách này sẽ kiểm tra mức độ hiểu biết của bạn về cách xử lý cả những kiểu ngoại lệ cụ thể lẫn các lỗi bất ngờ không thuộc các danh mục đã định trước.

Chương trình sẽ nhận các đầu vào sau:

  • Một chuỗi testType biểu thị kiểu kiểm tra cần thực hiện ("string_convert", "math_operation", "array_access" hoặc "unknown_error")
  • Một chuỗi value1 dùng làm dữ liệu chính cho phép toán
  • Một chuỗi value2 dùng làm dữ liệu phụ cho một số phép toán

Chương trình của bạn cần:

  1. Tạo một hàm có tên performTest nhận ba tham số kiểu chuỗi
  2. Bên trong hàm, dùng cấu trúc if-else để xử lý các kiểu kiểm tra khác nhau:
  3. Nếu testType là "string_convert": dùng std::stoi để chuyển value1 thành số nguyên rồi in ra
  4. Nếu testType là "math_operation": dùng std::stoi để chuyển cả value1 và value2 thành số nguyên, sau đó chia value1 cho value2 rồi in kết quả
  5. Nếu testType là "array_access": tạo một chuỗi "Programming", dùng std::stoi để chuyển value1 thành chỉ số nguyên, sau đó dùng str.at(index) để truy cập ký tự tại chỉ số đó và in ra. Phương thức .at() tự động ném std::out_of_range nếu chỉ số không hợp lệ: không cần kiểm tra giới hạn thủ công
  6. Nếu testType là "unknown_error": ném một giá trị số nguyên 999
  7. Trong hàm main, gọi performTest bên trong khối try
  8. Dùng nhiều khối catch để xử lý ngoại lệ theo đúng thứ tự sau:
  9. Thứ nhất: std::invalid_argument& cho trường hợp chuyển chuỗi thành số không hợp lệ
  10. Thứ hai: std::out_of_range& cho số quá lớn hoặc chỉ số chuỗi vượt giới hạn
  11. Thứ ba: catch(...) làm trình xử lý bắt tất cả các kiểu ngoại lệ khác

Dùng định dạng đầu ra chính xác sau:

Với các phép toán thành công:

Success: [result_value]

Với các kiểu ngoại lệ khác nhau:

Invalid argument caught
Out of range caught
Unknown exception caught

Hãy nhớ đặt trình xử lý bắt tất cả catch(...) ở cuối vì C++ kiểm tra các khối catch theo thứ tự. Trình xử lý này sẽ bắt mọi kiểu ngoại lệ chưa được xử lý bởi các khối catch cụ thể đứng trước, bao gồm cả ngoại lệ số nguyên được ném trong trường hợp "unknown_error". Trình xử lý bắt tất cả tạo một lớp bảo vệ trước các lỗi bất ngờ, đồng thời vẫn cho phép xử lý cụ thể những kiểu ngoại lệ đã biết.

Tự làm thử

#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;

// TODO: Viết code ở đây để tạo hàm (function) performTest

int main() {
    // Đọc đầu vào
    string testType;
    string value1;
    string value2;
    
    cin >> testType;
    cin >> value1;
    cin >> value2;
    
    // TODO: Viết code bên dưới để triển khai các khối lệnh try-catch và gọi performTest
    
    return 0;
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Logic và luồng chương trình

Tự luyện tập: Trình biên dịch C++ online