開発環境
- 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(原著)、望月 康司(翻訳)、クイープ(翻訳) 、オライリー・ジャパン)のⅣ部(高度なプログラミング概念)の18章(演算子のオーバーロード)、18.6(プログラミング実習)、実習 18-5.を解いてみる。
その他参考書籍
- C++プログラミング入門 (グレゴリー サティア (著)、ダウグ ブラウン (著)、Gregory Satir (原著)、Doug Brown (原著)、望月 康司 (翻訳)、谷口 功 (翻訳)、オライリージャパン)
実習 18-5.
コード(BBEdit, Emacs)
my_date2.h
#ifndef __my_date2_h__
#define __my_date2_h__
#include <iostream>
#include <iomanip>
namespace my_date2 {
const int DAYS_PER_MONTH[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
class date {
private:
int month;
int day;
int year;
static bool is_leap (int year)
{
return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0) ? true:
false;
}
public:
date () {
month = 1;
day = 1;
year = 0;
}
date (int m, int d, int y) {
month = m;
day = d;
year = y;
}
// date (const date& old_date);
// ~date ();
// date operator = (const date& old_date);
date operator += (const date& op2)
{
return (*this) + op2;
}
date operator -= (const date& op2)
{
return (*this) - op2;
}
friend date operator + (const date& op1, const date& op2);
friend date operator - (const date& op1, const date& op2);
friend std::ostream& operator << (std::ostream& out_file, const date& d);
friend std::istream& operator >> (std::istream& in_file, date& d);
};
inline std::ostream& operator << (std::ostream& out_file, const date& d)
{
out_file << std::setw(2) << std::setfill('0') << d.month << '/' <<
std::setw(2) << std::setfill('0') << d.day << '/' <<
std::setw(2) << std::setfill('0') << d.year;
return (out_file);
}
extern date operator + (const date& op1, const date& op2);
extern date operator - (const date& op1, const date& op2);
extern std::istream& operator >> (std::istream& in_file, date&d);
}
#endif /*__my_date2_h__*/
my_date2.cpp
#include <iostream>
#include "my_date2.h"
namespace my_date2 {
date operator + (const date& op1, const date& op2)
{
int month = op1.month + op2.month;
int day = op1.day + op2.day;
int year = op1.year + op2.year;
while (month > 12 || day > DAYS_PER_MONTH[month - 1]) {
if (month > 12) {
month -= 12;
++year;
}
else {
if (month == 2 && date::is_leap(year)) {
if (day == 29) break;
day -= 29;
}
else
day -= DAYS_PER_MONTH[month - 1];
++month;
}
}
return date(month, day, year);
}
date operator - (const date& op1, const date& op2)
{
int year = op1.year - op2.year;
int month = op1.month - op2.month;
int day = op1.day - op2.day;
if (month < 1) {
month += 12;
--year;
}
while (!(day > 0 && day <= DAYS_PER_MONTH[month - 1])) {
if (date::is_leap(year)) {
if (!(day > 0)) {
if (month == 3)
day += 29;
else
day += DAYS_PER_MONTH[month - 2];
--month;
}
else {
if (month == 2) {
if (day == 29) break;
day -= 29;
}
else
day -= DAYS_PER_MONTH[month - 1];
++month;
}
}
else {
if (!(day > 0)) {
day += DAYS_PER_MONTH[month - 2];
--month;
}
else {
day -= DAYS_PER_MONTH[month - 1];
++month;
}
}
if (month < 1) {
month += 12;
--year;
}
}
return date(month, day, year);
}
std::istream& operator >> (std::istream& in_file, date& d)
{
int month;
int day;
int year;
char ch;
month = 1;
day = 1;
year = 0;
std::istream::sentry the_sentry(in_file, true);
if (the_sentry) {
if (in_file.fail()) return (in_file);
in_file >> month;
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 >> day;
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 >> year;
if (in_file.fail()) return (in_file);
d.month = month;
d.day = day;
d.year = year;
}
else
in_file.setstate(std::ios::failbit);
return (in_file);
}
}
test_my_date2.cpp
#include <iostream>
#include "my_date2.h"
int main(int argc, char *argv[])
{
my_date2::date d0;
my_date2::date d1(4, 1, 0);
my_date2::date d2(12, 31, 0);
my_date2::date d3;
std::cout << d0 << "(01/01/00)\n";
std::cout << d1 << "(04/01/00)\n";
std::cout << d2 << "(12/31/00)\n";
std::cout << "日付を入力(MM/DD/YY) >> ";
std::cin >> d3;
std::cout << d3 << '\n';
std::cout << d0 << " + " << d1 << " = " << d0 + d1 << std::endl;
std::cout << d1 << " + " << d0 << " = " << d1 + d0 << std::endl;
std::cout << d1 << " + " << d2 << " = " << d1 + d2 << std::endl;
std::cout << d2 << " + " << d1 << " = " << d2 + d1 << std::endl;
std::cout << d2 << " + " << d3 << " = " << d2 + d3 << std::endl;
std::cout << d3 << " + " << d2 << " = " << d3 + d2 << std::endl;
std::cout << d0 << " - " << d1 << " = " << d0 - d1 << std::endl;
std::cout << d1 << " - " << d0 << " = " << d1 - d0 << std::endl;
std::cout << d1 << " - " << d2 << " = " << d1 - d2 << std::endl;
std::cout << d2 << " - " << d1 << " = " << d2 - d1 << std::endl;
std::cout << d2 << " - " << d3 << " = " << d2 - d3 << std::endl;
std::cout << d3 << " - " << d2 << " = " << d3 - d2 << std::endl;
return (0);
}
Makefile
CC=g++
CFLAGS=-g -Wall
all: test_my_date2
test_my_date2: test_my_date2.cpp my_date2.o
${CC} ${CFLAGS} -o test_my_date2 test_my_date2.cpp my_date2.o
my_date2.o: my_date2.cpp my_date2.h
${CC} -c -o my_date2.o my_date2.cpp
clean:
rm test_my_date2
入出力結果(Terminal)
$ make && ./test_my_date2 make && ./test_my_date2 g++ -c -o my_date2.o my_date2.cpp g++ -g -Wall -o test_my_date2 test_my_date2.cpp my_date2.o 01/01/00(01/01/00) 04/01/00(04/01/00) 12/31/00(12/31/00) 日付を入力(MM/DD/YY) >> 1/29/3 1/29/3 01/29/03 01/01/00 + 04/01/00 = 05/02/00 04/01/00 + 01/01/00 = 05/02/00 04/01/00 + 12/31/00 = 05/02/01 12/31/00 + 04/01/00 = 05/02/01 12/31/00 + 01/29/03 = 02/29/04 01/29/03 + 12/31/00 = 02/29/04 01/01/00 - 04/01/00 = 08/31/-1 04/01/00 - 01/01/00 = 02/29/00 04/01/00 - 12/31/00 = 03/01/-1 12/31/00 - 04/01/00 = 08/30/00 12/31/00 - 01/29/03 = 11/02/-3 01/29/03 - 12/31/00 = 12/30/01 $
0 コメント:
コメントを投稿