開発環境
- OS X Mavericks - Apple, ときどきWindows 8.1 + Cygwin64, MinGW (OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- C++ (プログラミング言語)
- g++(コンパイラ)
C++実践プログラミング (スティーブ オウアルライン (著)、Steve Oualline (原著)、Steve Oualline(原著)、望月 康司(翻訳)、クイープ(翻訳) 、オライリー・ジャパン)のⅤ部(言語のその他の機能)の22章(例外)、22.3(プログラミング実習)、実習 22-2.を解いてみる。
その他参考書籍
- C++プログラミング入門 (グレゴリー サティア (著)、ダウグ ブラウン (著)、Gregory Satir (原著)、Doug Brown (原著)、望月 康司 (翻訳)、谷口 功 (翻訳)、オライリージャパン)
実習 22-2.
コード(BBEdit, Emacs)
fraction.h
#ifndef __fraction_h__ #define __fraction_h__ #include <iostream> #include <cstdlib> class zero_div_err { public: const std::string what; zero_div_err(const std::string& i_what) : what(i_what) {} }; class fraction { private: int n; int d; static int gcd(int m, int n) { int t; m = m < 0 ? -m : m; n = n < 0 ? -n : n; if (m < n) { t = m; m = n; n = t; } if (n == 0) return m; return gcd(n, m % n); } public: fraction() { n = 0; d = 1; } fraction(int a, int b) { if (b == 0) { throw zero_div_err("division by zero"); } int t = gcd(a, b); n = a / t; d = b / t; } fraction(const fraction& old_fraction) { fraction(old_fraction.n, old_fraction.d); } ~fraction(){} fraction operator = (const fraction& old_fraction) { n = old_fraction.n; d = old_fraction.d; return (*this); } fraction& operator += (const fraction& old_fraction) { (*this) = (*this) + old_fraction; return (*this); } fraction& operator += (int x) { (*this) = (*this) + fraction(x, 1); return (*this); } fraction& operator -= (const fraction& old_fraction) { (*this) = (*this) - old_fraction; return (*this); } fraction& operator -= (int x) { (*this) = (*this) - fraction(x, 1); return (*this); } fraction& operator *= (const fraction& old_fraction) { (*this) = (*this) * old_fraction; return (*this); } fraction& operator *= (int x) { (*this) = (*this) * fraction(x, 1); return (*this); } fraction& operator /= (const fraction& old_fraction) { (*this) = (*this) / old_fraction; return (*this); } fraction& operator /= (int x) { (*this) = (*this) / fraction(x, 1); return (*this); } friend fraction operator + (const fraction& op1, const fraction& op2); friend fraction operator + (const fraction& op1, int op2); friend fraction operator + (int op1, const fraction& op2); friend fraction operator - (const fraction& op1, const fraction& op2); friend fraction operator - (const fraction& op1, int op2); friend fraction operator - (int op1, const fraction& op2); friend fraction operator * (const fraction& op1, const fraction& op2); friend fraction operator * (const fraction& op1, int op2); friend fraction operator * (int op1, const fraction& op2); friend fraction operator / (const fraction& op1, const fraction& op2); friend fraction operator / (const fraction& op1, int op2); friend fraction operator / (int op1, const fraction& op2); friend std::ostream& operator << (std::ostream& out_file, const fraction& r); friend std::istream& operator >> (std::istream& in_file, fraction& r); }; inline fraction operator + (const fraction& op1, const fraction& op2) { int n1 = op1.n; int d1 = op1.d; int n2 = op2.n; int d2 = op2.d; int n = n1 * d2 + n2 * d1; int d = d1 * d2; int t = fraction::gcd(n, d); return fraction(n / t, d / t); } inline fraction operator + (const fraction& op1, int op2) { return op1 + fraction(op2, 1); } inline fraction operator + (int op1, const fraction& op2) { return fraction(op1, 1) + op2; } inline fraction operator - (const fraction& op1, const fraction& op2) { int n1 = op1.n; int d1 = op1.d; int n2 = op2.n; int d2 = op2.d; int n = n1 * d2 - n2 * d1; int d = d1 * d2; int t = fraction::gcd(n, d); return fraction(n / t, d / t); } inline fraction operator - (const fraction& op1, int op2) { return op1 - fraction(op2, 1); } inline fraction operator - (int op1, const fraction& op2) { return fraction(op1, 1) - op2; } inline fraction operator * (const fraction& op1, const fraction& op2) { int n1 = op1.n; int d1 = op1.d; int n2 = op2.n; int d2 = op2.d; int n = n1 * n2; int d = d1 * d2; int t = fraction::gcd(n, d); return fraction(n / t, d / t); } inline fraction operator * (const fraction& op1, int op2) { return op1 * fraction(op2, 1); } inline fraction operator * (int op1, const fraction& op2) { return fraction(op1, 1) * op2; } inline fraction operator / (const fraction& op1, const fraction& op2) { int d2 = op2.d; if (d2 == 0) throw zero_div_err("division by zero"); int n2 = op2.n; return op1 * fraction(d2, n2); } inline fraction operator / (const fraction& op1, int op2) { return op1 / fraction(op2, 1); } inline fraction operator / (int op1, const fraction& op2) { return fraction(op1, 1) / op2; } inline std::ostream& operator << (std::ostream& out_file, const fraction& r) { if (r.d == 1) out_file << r.n; else out_file << r.n << '/' << r.d; return (out_file); } extern std::istream& operator >> (std::istream& in_file, fraction& r); #endif /* __fraction_h__ */
fraction.cpp
#include <iostream> #include "fraction.h" std::istream& operator >> (std::istream& in_file, fraction& r) { int n; char ch; int d; int t; r = fraction(); std::istream::sentry the_sentry(in_file, true); if (the_sentry) { if (in_file.fail()) return (in_file); in_file >> n; if (in_file.fail()) return (in_file); in_file >> ch; if (in_file.fail()) return (in_file); if (ch != '/') { in_file.setstate(std::ios::failbit); return (in_file); } in_file >> d; if (in_file.fail()) return (in_file); if (d == 0) throw zero_div_err("division by zero"); t = fraction::gcd(n, d); r.n = n / t; r.d = d / t; } else in_file.setstate(std::ios::failbit); return (in_file); }
test_fraction.h
#include <iostream> #include "fraction.h" int main(int argc, char *argv[]) { fraction r1(1, 3); fraction r2(1, 2); fraction r3; std::cout << r1 << " + " << r2 << " = " << r1 + r2 << std::endl; std::cout << r1 << " - " << r2 << " = " << r1 - r2 << std::endl; std::cout << r1 << " * " << r2 << " = " << r1 * r2 << std::endl; std::cout << r1 << " / " << r2 << " = " << r1 / r2 << std::endl; std::cout << "分数を入力(n/d): "; try { std::cin >> r3; } catch (zero_div_err& err) { std::cerr << "ZeroDivisionError: " << err.what << std::endl; } catch (...) { std::cerr << "Error: Unexpected exception occurred" << std::endl; } try { fraction r4(10, 0); } catch (zero_div_err& err) { std::cerr << "ZeroDivisionError: " << err.what << std::endl; } catch (...) { std::cerr << "Error: Unexpected exception occurred" << std::endl; } return (0); }
Makefile
CC=g++ CFLAGS=-g -Wall all: test_fraction test_fraction: test_fraction.cpp fraction.o fraction.h ${CC} ${CFLAGS} -o test_fraction test_fraction.cpp fraction.o fraction.o: fraction.cpp fraction.h ${CC} -c -o fraction.o fraction.cpp clean: rm test_fraction
入出力結果(Terminal)
$ make && ./test_fraction g++ -g -Wall -o test_fraction test_fraction.cpp fraction.o 1/3 + 1/2 = 5/6 1/3 - 1/2 = -1/6 1/3 * 1/2 = 1/6 1/3 / 1/2 = 2/3 分数を入力(n/d): 1/0 ZeroDivisionError: division by zero ZeroDivisionError: division by zero $
0 コメント:
コメントを投稿