2020-10-08 고급프로그래밍

Hyeonu_Chun·2021년 6월 22일
0

Absolute C++ 6th ed./Savitch Chap.7 Programming Project. 3

  1. 문제 기술
    필자는 일정 금액 이하의 각 자릿수 덧셈 연산만 하는 덧셈기의 구현을 요한다. 뿐만 아니라 일정 금액 초과 시 경고를 띄워 사용자에게 인지시키고 리셋이 가능하다.

  2. 설계 계획
    클래스 내부에 문제에서 요하는 데이터 멤버와 멤버 함수를 작성하고 금액의 합을 보여주는 멤버 함수를 추가한다. 생성자는 모두를 0으로 초기화하게 디폴트 생성자로 작성하고, 각 자리수의 덧셈 멤버 함수는 10을 초과할 시 해당 자릿수를 0으로 초기화하고 다음 자릿수를 하나 증가시키며 1000의 자리가 넘어갈 경우 오버플로우를 경고한다. 프로그램을 종료하지 않는 이상 리셋을 통해 덧셈기를 사용 가능하며 asdfor(ASDFOR)을 제외한 입력이나 1~9를 제외한 입력은 일체 예외 처리한다.

  3. 데이터 처리 과정
    먼저 Counter class type의 Counter이라는 객체를 생성한다. 따라서 Counter class의 디폴트 생성자가 호출되어 데이터 멤버를 초기화 시키고, 객체 생성을 완료한다. (이전의 입력을 고려해) 콘솔창을 리셋시키고 오버플로우를 검사한다. 덧셈기에 해당하는 기능을 나타내는 디스플레이를 출력하고, 사용자에게 해당 기능에 맞는 문자를 입력 받으면 기능을 수행한다. 자릿수 덧셈 시 추가로 숫자를 입력 받아 입력 받은 횟수만큼 해당 자릿수를 1씩 증가시킨다. 덧셈, 리셋 등의 기능을 수행한 뒤 무한루프문에 의해 기능은 0.5초의 딜레이를 가지고 다시금 수행 가능하게 되며 Q(q)를 입력 시 프로그램이 종료된다.

  4. 실행 결과 및 분석

#include <iostream>
#include <windows.h>
using namespace std;

class Counter {
private:
	bool overflowflag;
	int units;
	int tens;
	int hundreds;
	int thousands;

public:
	Counter() :units(0), tens(0), hundreds(0), thousands(0), overflowflag(false) {}
	~Counter() {}

	bool overflow();

	void reset();

	void incr1();
	void incr10();
	void incr100();
	void incr1000();

	void displayMoney();
};

void Counter::reset() {
	this->overflowflag = false;
	this->units = this->tens = this->hundreds = this->thousands = 0;
}


void Counter::displayMoney() {
	cout << "Total : $" << this->thousands << this->hundreds << "." << this->tens << this->units << endl;
}

bool Counter::overflow() {
	return this->overflowflag;
}

void Counter::incr1000() {
	if (this->thousands < 9) this->thousands++;
	else {
		this->thousands = 0;
		this->overflowflag = true;
	}
}

void Counter::incr100() {
	if (this->hundreds < 9) this->hundreds++;
	else {
		this->hundreds = 0;
		this->incr1000();
	}
}

void Counter::incr10() {
	if (this->tens < 9) this->tens++;
	else {
		this->tens = 0;
		this->incr100();
	}
}

void Counter::incr1() {
	if (this->units < 9) this->units++;
	else {
		this->units = 0;
		this->incr10();
	}
}

int inputDigit();

int main() {
	int i;
	int digit;
	char key;
	Counter Counter;

	while (true) {
		system("cls");
		if (Counter.overflow() == true) cout << "WARNING : Overflow has happened. Press r to reset." << endl;
		Counter.displayMoney();
		cout << "a - units\ns - tens\nd - hundreds\nf - thousands\no - check overflow\nr - reset\nQ - quit\nEnter a character : ";
		cin >> key;

		while(cin.get() != '\n') {
			key = 0;
		}

		switch (key) {
		case 'A':
		case 'a': {
			digit = inputDigit();
			for (i = 0; i < digit; i++) {
				Counter.incr1();
			}
		} break;
		case 'S':
		case 's': {
			digit = inputDigit();
			for (i = 0; i < digit; i++) {
				Counter.incr10();
			}
		} break;
		case 'D':
		case 'd': {
			digit = inputDigit();
			for (i = 0; i < digit; i++) {
				Counter.incr100();
			}
		} break;
		case 'F':
		case 'f': {
			digit = inputDigit();
			for (i = 0; i < digit; i++) {
				Counter.incr1000();
			}
		} break;
		case 'O':
		case 'o': {
			if (Counter.overflow() == true) {
				cout << "WARNING : Overflow has happened. Press r to reset." << endl;
			}
			else cout << "Overflow has not happended." << endl;
		} break;
		case 'R':
		case 'r': {
			cout << "Resetting..." << endl;
			Counter.reset();
		} break;
		case 'Q':
		case 'q': {
			cout << "Quitting..." << endl;;
			return 0;
		}
		default: {
			cout << "Please enter a CORRECT character." << endl;
			break;
		}
		}
		Sleep(500);
	}
}

int inputDigit() {
	int digit;
	cout << "Enter a digit between 1 and 9 : ";
	cin >> digit;
	if (cin.get() != '\n') {
		cout << "Please enter a CORRECT number." << endl;
		cin.clear();
		while (cin.get() != '\n') {}
		return 0;
	}
	if (cin.fail() == true) {
		cout << "Please enter a CORRECT number." << endl;
		cin.clear();
		while (cin.get() != '\n') {}
		return 0;
	}
	if (0 > digit || digit > 9) {
		cout << "Please enter a CORRECT number." << endl;
		return 0;
	}
	else return digit;
}


덧셈기의 원리에 따라 각 자릿수에 해당하는 숫자를 받고 더해서 오버플로우가 발생하면 경고하고 리셋을 권하는 형태의 결과물이 완성되었다. 기능적인 측면에서 오버플로우가 발생할 시 어떤 기능을 입력하던 경고문이 지속되어 ‘o’ 기능의 필요성을 느끼지는 못했다(독해를 잘못했을 가능성이 크다). 기존 과제에서 예외처리를 시행하지 않았었지만, 이번 과제의 경우 연속적인 입력의 경우 하나라도 잘못된 입력이 들어가면 무한루프에 빠지거나 원치 않은 기능을 수행하게 되어 최대한 노력을 해보았지만 깔끔하게 처리하지 못했다는 문제가 있다.

profile
Stay hungry, stay foolish

0개의 댓글