숫자 n을 입력받아 n번 실행되는 프로그램에서 실행도중 현재 실행을 종료하고 다음 실행으로 넘어가는 방법이 뭔가요?


만약 코드를 똑같이 10번 반복 실행하는 코드가 있다고 했을때 현재 단계가 5번째인데 실행도중 잘못된 입력값을 받으면 Wrong input을 출력하고 6번째 실행으로 넘어가고 싶습니다. exit을 쓰면 6번째 실행으로 넘어가지 않고 프로그램 전체가 아예 종료됩니다. try-catch를 쓰자니 throw 를 작성할때 조건식을 입력해야하는데 else 부분에 대해 뭐라고 조건을 작성야 할지 모르겠네요. a=b 이런식의 조건도 아니고 .. 사용하는 측이 아닌 원래 함수 안에 try-catch를 사용하면 안 된다고 알고 있기도 하고요.. 어떻게 이 문제를 해결할 수 있을까요??

만약에 주석부분의 exit(0)을 코드에서 없애면 Wrong Input과 함께 메인함수의 조건문 내 문장이 출력되어 버리는 상황입니다.

Wrong Input을 판단하는 부분을 메인 함수의 조건문으로로 올바르게 빼내서 Correct / InCorrect / Wrong Input 중에 하나만 출력되게 하면 문제가 해결되긴 하지만 이것 역시도 else부분의 조건에 대해 딱히 뭐라 조건식을 작성할지 몰라 시도도 못 하고 있네요 ㅠㅠ

bool areParanthesesBalanced(string exp) {   // 괄호에 따라 push, pop을 수행하는 함수
    ArrayStack<char>  S;
    for (int i = 0; i < exp.length(); i++) {
        if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')    // 열린 괄호는 push
            S.push(exp[i]);
        else if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']') { // 닫힌 괄호는 pop
            if (S.isEmpty() || !arePair(S.top(), exp[i]))   //비거나 짝이 안 맞으면 false 
                return false;
            else
                S.pop();
        }
        else {
            cout << "Wrong Input\n"; 
            exit(0); // exit으로 프로그램 전체를 종료하지 말고 현재 실행만 종료하려면?
        }
    }
    return S.isEmpty() ? true : false;
}

int main()
{
    int repeatcount = 0;
    cin >> repeatcount; // 프로그램의 반복횟수 입력

    while (repeatcount--) {
        string expression;
        cout << "Enter an expression: "; 
        cin >> expression;  // 괄호 및 키워드 입력

        if (expression == string("X") || expression == string("x")) // 실행 도중 X 입력시 프로그램 종료
            exit(0);
        else if (areParanthesesBalanced(expression)) {  // 괄호 짝, 순서가 맞으면 'Correct' 출력
            cout << "Correct\n";
        }
        else {  // 괄호 짝, 순서가 맞지 않으면 'InCorrect' 출력
            cout << "InCorrect\n";
        }
    }
}

  • 2016년 10월 02일에 작성됨

조회수 120


1 답변


좋아요
1
싫어요
채택취소하기

반환값을 bool이 아니라, 열거형으로 전달하면 해결될 듯 합니다.

// 반환값을 열거형으로 전달하는 방법.
// 간단한 코드에서는 이렇게 하는 것도 나쁘지 않습니다.
// 하지만, 나중에 복잡도 큰 프로젝트에서는 좀 더 구조화할 필요가 있습니다.
enum class ResultType
{
    WRONG_INPUT,
    CORRECT,
    INCORRECT,
};

// 객체를 매개변수로 넘겨받을 때는 const 레퍼런스를 사용하는 게 좋습니다.
// 그래야 불필요한 복사가 일어나지 않습니다.
ResultType areParanthesesBalanced(const string& exp) {   // 괄호에 따라 push, pop을 수행하는 함수
    ArrayStack<char> S;
    for (int i = 0; i < exp.length(); i++) {
        // 자주 사용할 참조값은 변수로 만들어주는 게 좋습니다.
        char curChar = exp[i];

        // 중괄호는 통일성 있게 사용하는 게 좋습니다.
        if (curChar == '(' || curChar == '{' || curChar == '[') {    // 열린 괄호는 push
            S.push(curChar);
        }
        else if (curChar == ')' || curChar == '}' || curChar == ']') { // 닫힌 괄호는 pop
            if (S.isEmpty() || !arePair(S.top(), curChar))   //비거나 짝이 안 맞으면 false 
                return ResultType::INCORRECT;
            else
                S.pop();
        }
        else {
            return ResultType::WRONG_INPUT;
        }
    }
    return S.isEmpty() ? ResultType::CORRECT : ResultType::INCORRECT;
}

int main()
{
    int repeatcount = 0;
    cin >> repeatcount; // 프로그램의 반복횟수 입력

    // 여기서는 while보단 for문이 적합할 듯 합니다.
    // while (repeatcount--) {
    for (int i = 0; i < repeatcount; i++) {
        string expression;
        cout << "Enter an expression: ";
        cin >> expression;  // 괄호 및 키워드 입력

        // 일단 여기는 건들지 않았지만,
        // exit()는 왠만하면 사용하지 않는 게 좋습니다.
        if (expression == string("X") || expression == string("x")) // 실행 도중 X 입력시 프로그램 종료
            exit(0);

        // 열거형은 switch로 받으면 됩니다.
        switch (areParanthesesBalanced(expression)) {
        case ResultType::WRONG_INPUT:   // 잘못된 입력이 있을 경우
            cout << "Wrong Input\n";
            break; // 여기서의 break는 switch문을 빠져나간다는 의미입니다. 
        case ResultType::CORRECT:       // 괄호 짝, 순서가 맞으면
            cout << "Correct\n";
            break;
        case ResultType::INCORRECT:     // 괄호 짝, 순서가 맞지 않으면
            cout << "InCorrect\n";
            break;
        }
    }
}

PS. 질문하시는 코드들을 보면, 항상 exit(0)를 사용하시던데, 이는 별로 좋지 않은 습관입니다.

프로그램이 안전하게 종료되려면, 그에 따른 여러 작업들을 해줘야 합니다. 예를 들면, 프로그램 중간에 new를 통해 동적할당을 한 적이 있다면, 종료되기 전에 delete를 해줄 필요가 있습니다.

그런데, exit(0)과 같은 코드를 넣어버리면, 그 시점에서 강제로 종료되기 때문에 부가적인 작업들을 해줄 수 없습니다.

따라서, 프로그램의 최종적인 종료는 무조건 main함수의 return으로 이루어지게끔 코드를 작성하는 습관을 들이는 것이 좋습니다.

  • 2016년 10월 03일에 작성됨
    C++, C# 좋아합니다.

  • 감사합니다!! 궁금했었는데 딱 가려운 부분을 긁어주셨네요. 이번에도 많이 배워갑니다 ㅎㅎ 반환값을 열거법으로 사용하는 방법은 간단한 코드일때 사용하는 방법인가보네요. exit은 강제종료같은 개념인 것 같아서 return 0 로 바꾸었습니다! 한 가지만 여쭈어보자면 상황에따라 어떤 기준으로 for과 while중 선택해서 사용하는건지 잘 모르겠습니다. 이 역시도 성능에 영향을 많이 주는 부분인가요?    이성우   2016.10.3 23:24     
  • 성능상의 문제라기보단 개념상의 문제입니다. for문은 어디서 어디까지 루프를 돈다는 개념, while문은 어떤 조건 하에서 그 조건이 위반될 때까지 루프를 돈다는 개념입니다. 사실 똑같은 루프를 양쪽 다 구현 가능하지만, 의미적으로 의도하는 상황에 맞추어서 루프문을 쓰는 게 좋습니다. 위 코드에서 while을 for로 바꾼 이유는, repeatcount 만큼 반복한다는 의미는 for문이 더 알맞기 때문입니다.    Subin Park   2016.10.4 10:31     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close