C++ stoi() 함수와 예외 처리

조회수 8905회
std::string str = "129380129831213981";
int conv = std::stoi(str);

이 코드를 실행하면 변환하려는 숫자가 int의 범위를 초과하여 Out of range 예외가 발생합니다.

그래서 아래와 같이 try~catch문을 작성했는데

try {
    std::string str = "129380129831213981";
    int conv = std::stoi(str);
} catch (const std::string& expn) {
    std::cout << expn << ": Out of integer's range\n";
}

이렇게 해도 예외가 처리되지 않고 강제 terminate 됩니다.

'Stack unwinding' 원칙에 따라 try문에서 stoi() 함수를 호출하던 중 발생한 예외 데이터는 다시 try문으로 돌아오고, 이 데이터가 catch문으로 던져져서 처리되는 게 아닌가요?

제가 뭔가 잘못 이해하고 있는 건지 답변 부탁드려요.

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 자문 자답 하셨지만 보충을 해보겠습니다.

    std::stoi()std::string을 int로 변환해 주는 함수입니다. 따라서 int 의 표현 범위를 넘는 문자열이 입력될 경우에는 std::out_of_range 예외가 발생하니다.

    통산 int 는 최소 -2147483648에서 최대 2147483647 까지 표현할 수 있습니다. 변환에 사용하셨던 "129380129831213981"는 int의 표현 범위를 넘어서기 때문에 std::stoll()을 사용해야합니다.

    try~catch에서 예외를 정상적으로 받지 못한 이유는 catch 구문에서 던저진 예외의 타입이 아닌 std::string을 받도록 작성하였기 때문입니다. 간혹 던저질 예외가 어떤 것인지 몰라서 이러한 실수를 하게 되는데 이때는 std::exception이나 ...을 이용하시면 대부분의 예외를 받을 수 있습니다.

    C++ 표준 라이브러리에서 발생하는 모든 예외는 std::exception을 상속하고 있습니다. ...은 모든 예외라는 의미 입니다. 따라서 아래처럼 작성하면 대부분의 예외를 받을 수 있습니다.

    try {
        std::string str = "129380129831213981";
        int conv = std::stoi(str);
    } catch (const std::exception& expn) {
        std::cout << expn.what() << ": Out of integer's range\n";
    } catch (...) {
        std::cout << ": Unknown error\n";
    }
    

    참고로 Stack unwinding이란 예외가 던저질 때 catch에 도달하 기까지의 스택이 정리되는 방법을 의미하는 것입니다. try 지점으로 돌아오는건 Stack unwinding 때문이 아니라 try~catch 의 문법적 기능입니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)