Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

B: Etc

This appendix contains files that are required to build the examples in Volume 2.

//: :require.h
// Test for error conditions in programs.
#ifndef REQUIRE_H
#define REQUIRE_H
#include <cstdio>
#include <cstdlib>
#include <fstream>
 
inline void require(bool requirement,
const char* msg = "Requirement failed") {
// Local "using namespace std" for old compilers:
using namespace std;
if(!requirement) {
fputs(msg, stderr);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
}
 
inline void requireArgs(int argc, int args,
const char* msg = "Must use %d arguments") {
using namespace std;
if(argc != args + 1) {
fprintf(stderr, msg, args);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
}
 
inline void requireMinArgs(int argc, int minArgs,
const char* msg = "Must use at least %d arguments") {
using namespace std;
if(argc < minArgs + 1) {
fprintf(stderr, msg, minArgs);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
}
 
inline void assure(std::ifstream& in,
const char* filename = "") {
using namespace std;
if(!in) {
fprintf(stderr, "Could not open file %s\n", filename);
exit(EXIT_FAILURE);
}
}
 
inline void assure(std::ofstream& in,
const char* filename = "") {
using namespace std;
if(!in) {
fprintf(stderr, "Could not open file %s\n", filename);
exit(EXIT_FAILURE);
}
}
 
inline void assure(std::fstream& in,
const char* filename = "") {
using namespace std;
if(!in) {
fprintf(stderr, "Could not open file %s\n", filename);
exit(EXIT_FAILURE);
}
}
#endif // REQUIRE_H ///:~
 
//: C0B:Dummy.cpp
// To give the makefile at least
// one target for this directory.
int main() {} ///:~
 

The Date class files:

//: C02:Date.h
#ifndef DATE_H
#define DATE_H
#include <string>
#include <stdexcept>
#include <iosfwd>
 
class Date {
int year, month, day;
int compare(const Date&) const;
static int daysInPrevMonth(int year, int mon);
public:
// A class for date calculations
struct Duration {
int years, months, days;
Duration(int y, int m, int d)
: years(y), months(m) ,days(d) {}
};
// An exception class
struct DateError : public std::logic_error {
DateError(const std::string& msg = "")
: std::logic_error(msg) {}
};
Date();
Date(int, int, int) throw(DateError);
Date(const std::string&) throw(DateError);
int getYear() const;
int getMonth() const;
int getDay() const;
std::string toString() const;
friend Duration duration(const Date&, const Date&);
friend bool operator<(const Date&, const Date&);
friend bool operator<=(const Date&, const Date&);
friend bool operator>(const Date&, const Date&);
friend bool operator>=(const Date&, const Date&);
friend bool operator==(const Date&, const Date&);
friend bool operator!=(const Date&, const Date&);
friend std::ostream& operator<<(std::ostream&,
const Date&);
friend std::istream& operator>>(std::istream&, Date&);
};
#endif // DATE_H ///:~
 
//: C02:Date.cpp {O}
#include "Date.h"
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <string>
#include <algorithm> // For swap()
#include <ctime>
#include <cassert>
#include <iomanip>
using namespace std;
 
namespace {
const int daysInMonth[][13] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
inline bool isleap(int y) {
return y%4 == 0 && y%100 != 0 || y%400 == 0;
}
}
 
Date::Date() {
// Get current date
time_t tval = time(0);
struct tm *now = localtime(&tval);
year = now->tm_year + 1900;
month = now->tm_mon + 1;
day = now->tm_mday;
}
 
Date::Date(int yr,int mon,int dy) throw(Date::DateError) {
if(!(1 <= mon && mon <= 12))
throw DateError("Bad month in Date ctor");
if(!(1 <= dy && dy <= daysInMonth[isleap(year)][mon]))
throw DateError("Bad day in Date ctor");
year = yr;
month = mon;
day = dy;
}
 
Date::Date(const std::string& s) throw(Date::DateError) {
// Assume YYYYMMDD format
if(!(s.size() == 8))
throw DateError("Bad string in Date ctor");
for(int n = 8; --n >= 0;)
if(!isdigit(s[n]))
throw DateError("Bad string in Date ctor");
string buf = s.substr(0, 4);
year = atoi(buf.c_str());
buf = s.substr(4, 2);
month = atoi(buf.c_str());
buf = s.substr(6, 2);
day = atoi(buf.c_str());
if(!(1 <= month && month <= 12))
throw DateError("Bad month in Date ctor");
if(!(1 <= day && day <=
daysInMonth[isleap(year)][month]))
throw DateError("Bad day in Date ctor");
}
 
int Date::getYear() const { return year; }
 
int Date::getMonth() const { return month; }
 
int Date::getDay() const { return day; }
 
string Date::toString() const {
ostringstream os;
os.fill('0');
os << setw(4) << year
<< setw(2) << month
<< setw(2) << day;
return os.str();
}
 
int Date::compare(const Date& d2) const {
int result = year - d2.year;
if(result == 0) {
result = month - d2.month;
if(result == 0)
result = day - d2.day;
}
return result;
}
 
int Date::daysInPrevMonth(int year, int month) {
if(month == 1) {
--year;
month = 12;
}
else
--month;
return daysInMonth[isleap(year)][month];
}
 
bool operator<(const Date& d1, const Date& d2) {
return d1.compare(d2) < 0;
}
bool operator<=(const Date& d1, const Date& d2) {
return d1 < d2 || d1 == d2;
}
bool operator>(const Date& d1, const Date& d2) {
return !(d1 < d2) && !(d1 == d2);
}
bool operator>=(const Date& d1, const Date& d2) {
return !(d1 < d2);
}
bool operator==(const Date& d1, const Date& d2) {
return d1.compare(d2) == 0;
}
bool operator!=(const Date& d1, const Date& d2) {
return !(d1 == d2);
}
 
Date::Duration
duration(const Date& date1, const Date& date2) {
int y1 = date1.year;
int y2 = date2.year;
int m1 = date1.month;
int m2 = date2.month;
int d1 = date1.day;
int d2 = date2.day;
 
// Compute the compare
int order = date1.compare(date2);
if(order == 0)
return Date::Duration(0,0,0);
else if(order > 0) {
// Make date1 precede date2 locally
using std::swap;
swap(y1, y2);
swap(m1, m2);
swap(d1, d2);
}
 
int years = y2 - y1;
int months = m2 - m1;
int days = d2 - d1;
assert(years > 0 ||
years == 0 && months > 0 ||
years == 0 && months == 0 && days > 0);
 
// Do the obvious corrections (must adjust days
// before months!) - This is a loop in case the
// previous month is February, and days < -28.
int lastMonth = m2;
int lastYear = y2;
while(days < 0) {
// Borrow from month
assert(months > 0);
days += Date::daysInPrevMonth(
lastYear, lastMonth--);
--months;
}
 
if(months < 0) {
// Borrow from year
assert(years > 0);
months += 12;
--years;
}
return Date::Duration(years, months, days);
}
 
ostream& operator<<(ostream& os, const Date& d) {
char fillc = os.fill('0');
os << setw(2) << d.getMonth() << -
<< setw(2) << d.getDay() << -
<< setw(4) << setfill(fillc) << d.getYear();
return os;
}
 
istream& operator>>(istream& is, Date& d) {
is >> d.month;
char dash;
is >> dash;
if(dash != '-')
is.setstate(ios::failbit);
is >> d.day;
is >> dash;
if(dash != '-')
is.setstate(ios::failbit);
is >> d.year;
return is;
} ///:~
 

The file test.txt used in Chapter 6:

//: C06:Test.txt
f a f d A G f d F a A F h f A d f f a a
///:~
 

 


Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire