2017-02-06 3 views
0

거의 모든 Linux 운영 체제 에서처럼 사용자 유형이 숨겨진 상태로 유지되도록 Windows/Linux 콘솔에서 입력을받습니다. 다음 스 니펫에 의해 던져진 예외를 어떻게 정상적으로 처리해야합니까?예외 처리 C++

#ifdef _WIN32 
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 
DWORD mode = 0; 
GetConsoleMode(hStdin, &mode); 
SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT)); 

std::string sTempPass; 
getline(cin, sTempPass); 
SetConsoleMode(hStdin, mode); 

#elif __linux__ 
termios oldt; 
tcgetattr(STDIN_FILENO, &oldt); 
termios newt = oldt; 
newt.c_lflag &= ~ECHO; 
tcsetattr(STDIN_FILENO, TCSANOW, &newt); 

std::string sTempPass; 
getline(cin, sTempPass); 
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 

그리고 가능한 시나리오가 무엇 위의 조각은 예외의 다른 유형을 던질 수 있으며,이 작업을 수행하는 다른 플랫폼에 독립적 인 방법은 무엇입니까?

+0

게시 한 코드는 예외를 발생시키지 않습니다. –

+1

@ el.pescado :'getline (cin, sTempPass);'호출이 있습니다. 적어도 이것은 출력 문자열 버퍼의 크기를 조정하기 때문에'std :: bad_alloc' 예외를 발생시킬 수 있습니다. 코드 * 예외를 throw 할 수 있습니다. – IInspectable

+0

@IInspectable 네 말이 맞아. –

답변

1

예외가 발생할 경우 롤백 작업은 일반적으로 C++에서 소멸자를 실행하여 구현됩니다. 귀하의 경우는 현재 상태를 저장하는 클래스를 생성 할 수 있으며, 소멸자에서 복원 : 호출 코드는 단순히 자동 저장 기간을 가진 객체를 구축

struct ConsoleMode { 
    DWORD mode; 
    HANDLE handle; 
    ConsoleMode(const HANDLE h) : handle(h) { 
     ::GetConsoleMode(handle, &mode); 
    } 
    ~ConsoleMode() { 
     ::SetConsoleMode(handle, mode); 
    } 
} 

하고, 긴장을 풀기 자동 스택 정리를 잎 :

HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 
{ 
    ConsoleMode savedState(hStdin); 
    ::SetConsoleMode(hStdin, savedState.mode & (~ENABLE_ECHO_INPUT)); 

    std::string sTempPass; 
    getline(cin, sTempPass); 

    // savedState goes out of scope and runs its destructor to restore state. 
    // The destructor runs as part of stack unwinding in case of an exception as well. 
} 

Linux 구현은 각 시스템 호출과 구성원이 적절하게 조정 된 것과 유사합니다.

+0

hStdin = GetStdHandle을 처리 할 수 ​​있습니다 (STD_INPUT_HANDLE); 핸들이 반환되지 않는 경우 예외가 발생합니까? @Insnsable –

+0

@Milind : Windows API는 C 인터페이스로 제공됩니다. 오류는 리턴 값을 통해서만보고됩니다. 이 경우 [GetStdHandle] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms683231.aspx)이 실패하면 'INVALID_HANDLE_VALUE'(또는 'NULL')을 반환합니다. 예외가 발생하더라도 전역 상태가 변경되기 전에 호출이 이루어 지므로 중요하지 않습니다. – IInspectable

+0

, 감사합니다 (Y) –