|
|
[13장 연습문제]
// 1
// 13.h
#ifndef HEADER_13_HPP
#define HEADER_13_HPP
namespace header_13 {
int sum(int a, int b);
}
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
int main() {
try {
cout << sum(2, 5) <<endl;
cout << sum(-2, 5) <<endl;
}
catch(const char* s) {cout << s << endl;}
}
// 13_func.cpp
#include "13.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
namespace header_13 {
int sum(int a, int b) {
if(a>b) throw "잘못된 입력";
if(a<0||b<0) throw "음수 처리 안됨";
int sum = 0;
for(int i = a; i <= b; i++) {
sum += i;
}
return sum;
}
}
// 2
// 13.h
#ifndef HEADER_13_HPP
#define HEADER_13_HPP
namespace header_13 {
char scoreToGrade(int a) throw(char*);
}
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
int main() {
int score;
while(true) {
cout << "점수 입력>> ";
cin >> score;
try {
cout << score << "점은 ";
cout << scoreToGrade(score); }
catch(char* s) { cout << s; }
cout << endl;
}
}
// 13_func.cpp
#include "13.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
namespace header_13 {
char scoreToGrade(int a) throw(char*) {
if(a < 0 || a > 100) throw "오류";
a /= 10;
if(a ==10 || a == 9 ) return 'A';
if(a == 8) return 'B';
if(a == 7) return 'C';
else return 'F';
}
}
// 3
// 13.h
#ifndef HEADER_13_HPP
#define HEADER_13_HPP
namespace header_13 {
int get() throw(const char*);
}
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
int main() {
while(true) {
try {
int x = get(), y = get();
cout << x * y << endl;
}
catch(const char* s) { cout << s << endl; }
}
}
// 13_func.cpp
#include "13.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
namespace header_13 {
int get() throw(const char*) {
cout << "정수 입력(1~9)>>";
int x; cin >> x;
if (x < 1 || x > 9) { throw "input fault"; }
return x;
}
}
// 4
// 13.h
#ifndef HEADER_13_HPP
#define HEADER_13_HPP
namespace header_13 {
int getfilesize(const char* file) throw(int);
}
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
int main() {
try {
int n = getfilesize("파일경로");
cout << "파일크기 = " << n << endl;
}
catch(int a) {
if(a == -1) cout << "파일명이 NULL입니다." << endl;
else if(a == -2) cout << "파일을 열기 실패했습니다." << endl;
}
try {
int m = getfilesize(NULL);
cout << "파일크기 = " << m << endl;
}
catch(int a) {
if(a == -1) cout << "파일명이 NULL입니다." << endl;
else if(a == -2) cout << "파일을 열기 실패했습니다." << endl;
}
}
// 13_func.cpp
#include "13.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
namespace header_13 {
int getfilesize(const char* file) throw(int) {
if (file == nullptr) throw -1;
ifstream in(file, ios::binary | ios::ate);
if (!in.is_open()) throw -2;
int size = static_cast<int>(in.tellg());
in.close();
return size;
}
}
// 5
// 13.h
// X
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
int main() {
int n;
cin.exceptions(ios::failbit);
while(true) {
try {
cout << "양수 입력>> ";
cin >> n;
if(n < 1 || n > 9) throw -1;
for(int i = 1; i < 10; i++) cout << n << 'x' << i << '=' << n*i << ' ';
cout << endl;
}
catch(ios_base::failure& e) {
cout << "숫자 형식이 아닙니다!" << endl;
cin.clear();
cin.ignore(100, '\n');
}
catch(int a) {
cout << "잘못된 입력입니다. 1~9 사이의 정수만 입력하세요" << endl;
}
}
}
// 13_func.cpp
// X
// 6
// 13.h
#ifndef HEADER_13_HPP
#define HEADER_13_HPP
namespace header_13 {
int* concat(int a[] ,int sizea, int b[], int sizeb);
}
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
int main() {
int a[] = {1, 2, 3, 4, 5}, b[] = {6, 7, 8, 9, 0};
try {
int* c = concat(a, 5, b, 5);
for(int i = 0; i < size(a) + size(b); i++) cout << c[i] << ' ';
delete[] c;
}
catch(int a) { cout << "오류 코드 : " << a << endl; }
}
// 13_func.cpp
#include "13.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
namespace header_13 {
int* concat(int a[] ,int sizea, int b[], int sizeb) throw(int) {
if(a == NULL || b == NULL) throw 1;
if(sizea == 0 || sizeb == 0) throw 0;
int* arr = new int[sizea+sizeb];
for (int i = 0; i < sizea; i++) arr[i] = a[i];
for (int i = 0; i < sizeb; i++) arr[sizea + i] = b[i];
return arr;
}
}
// 7
// 13.h
// X
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
int main() {
try {
ifstream fin("origin.txt", ios::binary);
if (!fin.is_open()) throw -1;
ofstream fout("copy.txt", ios::binary);
if (!fout.is_open()) throw -2;
char ch;
while (fin.get(ch)) fout.put(ch);
fin.close(); fout.close();
cout << "파일 복사 완료" << endl;
}
catch (int e) {
if (e == -1) cout << "원본 파일을 열 수 없습니다." << endl;
else if (e == -2) cout << "복사할 파일을 생성할 수 없습니다." << endl;
}
}
// 13_func.cpp
// X
// 8
// 13.h
#ifndef HEADER_13_HPP
#define HEADER_13_HPP
namespace header_13 {
int* copy(int* src, int size);
}
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
int main() {
int a[] = { 1, 2, 3, 4, 5 };
try {
int* arr = copy(a, 5);
for(int i = 0; i < 5; i++) cout << arr[i] << ' ';
cout << endl;
delete[] arr;
}
catch(int a) {
if(a == -1) {cout << "배열의 크기가 너무 작습니다." << endl; }
if(a == -2) {cout << "배열의 크기가 너무 큽니다." << endl;}
if(a == -3) {cout << "배열 할당에 실패했습니다." << endl;}
if(a == -4) {cout << "복사할 배열이 비어있습니다." << endl;}
}
}
// 13_func.cpp
#include "13.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
namespace header_13 {
int* copy(int* src, int size) {
if(size < 0) throw -1; if(size < 100) throw -2;
int* p = new int [size];
if(p == NULL) throw -3; if(src == NULL) throw -4;
for(int i = 0; i < size; i++) p[i] = src[i];
return p;
}
}
// 9
// 13.h
// X
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
#include "get.c"
int main() {
int n1 = get2(), n2 = get2();
cout << "곱은 " << n1 * n2 << "입니다." << endl;
return 0;
}
// 13_func.cpp
#include <stdio.h>
int get2() {
int c;
printf("숫자를 입력하세요>> ");
scanf("%d", &c);
return c;
}
// 10
// 13.h
// X
// 13_main.cpp
#include "13.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
using namespace header_13;
#include "print.c"
int main() {
printline(1);
printline(2);
printline(3);
}
// print.c
#include <stdio.h>
void printline(int count) {
int i;
for(i = 0; i< count; i++) printf("*");
printf("\n");
}
// [13장 정리문제]
// 1) 예외처리가 무엇인가
// 예외처리는 단순히 문법적 오류인 컴파일 에러와 달리 런타임 중에 발생하는 0 나누기나 메모리 할당 실패 같은 프로그램의 정상적인 실행 흐름을 방해하는 예외적 상황이 발생했을 때
// 이것을 감지하고 적절히 대응하여 시스템의 비정상 종료를 방지하여 소프트웨어의 견고성과 신뢰성을 확보하는 제어
메커니즘이다.
// 2) C 언어에서 예외처리 방법은
// C 언어에서의 예외처리는 별도의 키워드 없이 주로 함수의 반환값을 통한 상태 코드 전달이나 전역 변수인 errno를 확인하는 방식으로 이루어진다.
// 예를 들어 호출된 함수가 작업 실패 시 특정 상수를 반환하면 호출 측 if문이 활성화되어 즉각적으로 오류 여부를 판단하고
후속 처리를 수행한다.
// 이러한 방식의 예외처리 방식은 오류 발생 지점마다 조건문을 수동으로 작성해야 하므로 핵심 비즈니스 로직과 에러 처리
코드가 혼재되어 가독성이 떨어지며 실수를 유발할 수 있다.
// 3) C++ 언어에서 예외처리 방법은
// C++은 try, throw, catch라는 전용 키워드를 도입하여 예외 발생 지점과 처리 지점을 분리하는 구조의 메커니즘을 제공한다.
// throw를 통해 예외 객체를 던지면 실행 흐름이 즉시 중단되고 이를 처리할 수 있는 가장 가까운 catch 블록으로 제어권이
넘어가는 방식이며,
// 이 과정에서 스택 해제가 발생하여 지역 객체들의 소멸자가 자동으로 호출되는 등 자원 관리가 체계적으로 이루어진다.
// 그러나 예외 객체 생성 및 스택 해제 과정에서 오버헤드가 발생하며, 예외 안전성을 고려하지 않은 설계 시 메모리 누수가
발생할 수 있다.
// 4) C++ 코드에서 C 언어 함수를 호출하는 방법을 설명하시오
// C++에서 C 언어 함수를 호출하기 위해서는 extern "C" 지시어를 사용하여 C++의 네임 맹글링을 방지해야 한다.
// C++ 컴파일러는 함수 오버로딩을 지원하기 위해 함수 이름을 복잡하게 변환하는 것과 달리 C 컴파일러는 함수명을 그대로 유지하므로, 링크 단계에서 함수를 올바르게 찾을 수 있도록 해당 함수가 C 방식으로 컴파일되었음을 반드시 명시해야 한다.
// 또한 보편적으로 C 헤더 파일 내부에 __cplusplus 매크로를 활용해 조건부 컴파일 문구를 넣어 C와 C++ 환경 모두에서
호환되도록 설계하고,
// 수정 권한이 없는 외부 라이브러리인 경우 #include 문 전체를 extern "C" { ... }로 감싸서 링크 단계의 심볼 불일치 문제를
원천적으로 해결하는 것이 좋다.
[최종과제]
// 1
// final.hpp
// X
// final_main.cpp
#include "final.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
using namespace header_final;
int main() {
ifstream fin("data.txt");
string line, n, t, w, h, b;
while (getline(fin, line)) {
size_t start = line.find('=') + 2;
size_t end = line.find("//") - 1;
string val = line.substr(start, end - start);
if (line.find("Name") == 0) n = val;
else if (line.find("Type") == 0) t = val;
else if (line.find("Width") == 0) w = val;
else if (line.find("Height") == 0) h = val;
else if (line.find("Bits") == 0) b = val;
}
int pixels = stoi(w) * stoi(h);
int total_bits = pixels * stoi(b);
cout << "파일명 : " << n << "." << t << endl;
cout << "전체픽셀수 : " << w << "x" << h << "=" << pixels << "개" << endl;
cout << "전체비트수 : " << w << "x" << h << "x" << b << "=" << total_bits << "비트" << endl;
}
// final_func.cpp
// X
// 2
// final.hpp
#ifndef HEADER_final_HPP
#define HEADER_final_HPP
#include <string>
namespace header_final {
class Student {
std::string name;
int eng, math, sum;
double avg;
public:
Student() : name(""), eng(0), math(0), sum(0), avg(0.0) {}
friend std::ostream& operator<<(std::ostream& os, const Student& s);
friend std::istream& operator>>(std::istream& is, Student& s);
};
std::ostream& operator<<(std::ostream& os, const Student& s);
std::istream& operator>>(std::istream& is, Student& s);
}
#endif
// final_main.cpp
#include "final.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
using namespace header_final;
int main() {
Student a, b;
cin >> a >> b;
cout << a << b;
}
// final_func.cpp
#include "final.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
namespace header_final {
istream& operator>>(istream& is, Student& s) {
cout << "이름 : "; is >> s.name;
cout << "영어 : "; is >> s.eng;
cout << "수학 : "; is >> s.math;
s.sum = s.eng + s.math;
s.avg = s.sum / 2.0;
return is;
}
ostream& operator<<(ostream& os, const Student& s) {
os << "이름 : " << s.name << endl << "영어 : " << s.eng << endl;
os << "수학 : " << s.math << endl << "총점 : " << s.sum << endl;
os << "평균 : " << s.avg << endl;
return os;
}
}
|
|
