|
|
|
Class User Programming and the Standard
Containers |
|
|
|
|
|
|
Types and user-defined types |
|
The standard library |
|
Name spaces |
|
Class user programming with templates |
|
Basic containers & iterators |
|
list, stacks, strings, vectors, maps & sets |
|
Special iterators for I/O |
|
Examples of reusing software components |
|
Calculator — stack type |
|
Text justification — string type |
|
Employee security & spell checking — set
type |
|
Count unique words — map type |
|
Sorting a list of words — map type |
|
|
|
|
|
|
Testing time is reduced |
|
Investment can be amortized |
|
Labor can be divided |
|
Class libraries are key to reusable software |
|
Features of C++ that facilitate reuse are |
|
Inheritance, |
|
Polymorphism, |
|
Parameterized classes, and |
|
Similar syntax for built-ins as UDT (e.g., |
|
I/O, and |
|
Indexing containers) |
|
|
|
|
|
Examples |
|
stack<int> x; Stack of integers |
|
stack<stack<int> > y; Stack of
stack of
integers |
|
vector<int> z; An integer array
indexed by integers |
|
vector< vector<int> > a; A
two
dimensional array |
|
list<string> w; A doubly linked
list
of Strings |
|
When using parameterized types |
|
Implementation is often not a separate cpp file, |
|
The compilation process is slowed down, |
|
|
|
|
|
New feature allows multiple class libraries in
same client |
|
Syntax |
|
namespace foo {void bar(){
cout<<"foo::bar"; }} |
|
namespace xxx {void bar(){
cout<<"xxx::bar"; }} |
|
using namespace foo; |
|
main(){ |
|
bar(); |
|
xxx::bar(); |
|
return 0; |
|
} |
|
|
|
|
|
|
|
Problem: Simulate a simple hand-held calculator |
|
Interface of stack |
|
Syntax — how to call it |
|
Semantics — how to use it |
|
|
|
|
|
Implicit operations (value semantics) |
|
Create a stack |
|
Destroy a stack |
|
Assign a stack to another stack |
|
Operations |
|
Push an element |
|
pop an element |
|
The user-provider model |
|
calc.cpp is sometimes said to be a client |
|
stack.cpp (recently renamed to stack) is
sometimes said to be a server |
|
stack is independent of calculator programs |
|
Calc is independent of specific stack types |
|
|
|
|
|
|
See listings at end of chapter |
|
Source for algebraic notation with variables: |
|
lib\calc\main.cpp |
|
\lib\stlcalc\main.cpp |
|
|
|
|
|
|
C does not have a string type |
|
C programmers act as if it does |
|
string.h defines pseudo-strings |
|
vector of characters terminated by a null byte |
|
Pointers called “strings” |
|
Operations |
|
char* strcpy(char*, const char*); |
|
int strcmp(const char*, const char*); |
|
int strlen(const char*); |
|
Minimal compiler support |
|
|
|
|
|
char* max(char* p1, char* p2){ |
|
char array[10]; |
|
char* p3 = array; |
|
if(strcmp(p1, p2) > 0) |
|
strcpy(p3, p1); |
|
else |
|
strcpy(p3, p2); |
|
return p3; |
|
} |
|
|
|
|
|
|
Full value semantics |
|
Create string object with no default value |
|
Create string object with initial value of type char* |
|
Create string object with initial value of type string |
|
Pass by value |
|
Return as function value |
|
Assign one string object to another |
|
Automatically deallocate string objects |
|
|
|
|
|
Explicit operations |
|
Length |
|
Substrings |
|
Character search |
|
Concatenation |
|
Comparison |
|
I/O |
|
|
|
|
|
|
|
#include <string> |
|
using namespace std; |
|
string line; |
|
string word("hello"); // string
word="hello"; |
|
string word2 = word; |
|
string word3(word2); |
|
|
|
|
|
int len; |
|
len = line.length(); // 0 |
|
len = word.length(); // 5 |
|
|
|
|
|
|
Two arguments: |
|
First argument indicates position |
|
Start counting from zero |
|
Second (optional) argument indicates size |
|
Start counting from one, |
|
string letters("abcdefg"); |
|
letters.substr(1, 3) // “bcd” |
|
|
|
|
|
|
Searching |
|
size_type pos; |
|
pos = letters.find('a'); // 0 |
|
pos =
letters.find("d"); //
3 |
|
pos = letters.find('x'); // -1 |
|
Testing |
|
Strategy #1 |
|
if(pos == (size_type)-1)
cout << "not
found"; |
|
Strategy #2 |
|
if(pos == string::npos) cout << "not
found"; |
|
|
|
|
|
char ch; |
|
ch = letters[3]; // ‘d’ |
|
letters[3] = 'x'; // “abcxefg” |
|
letters[letters.index('x')] = 'y'; |
|
// “abcyefg” |
|
|
|
|
|
word + "World" //
“helloWorld” |
|
line + word // “hello” |
|
line + " " + word // “ hello” |
|
line.substr(0,pos) + " " +
line.substr(pos) ; |
|
line += " " + word; |
|
|
|
|
|
|
|
cin >> word; |
|
cout << word<< endl ; |
|
while (cin >> word) |
|
cout << word << endl ; |
|
|
|
|
|
line = word; |
|
line = line + " " + word; |
|
word = letters.substr(0,4); // “ abcd” |
|
|
|
|
|
Passing parameters by value |
|
void funcl ( string word ); |
|
funcl ( letters ) ; |
|
Return by value |
|
string func2( ); |
|
word = func2( ); |
|
|
|
|
|
word.length(); |
|
How many |
|
Actual arguments? |
|
Arguments in argument list? |
|
|
|
|
|
|
|
Write a program that converts words into
pig-latin. |
|
input: |
|
The quick brown fox jumped over the lazy dog’s
back 1234567890 times. The lazy dog jumped over the quick brown fox’s back
1234567890 times. |
|
output: |
|
Hetay uickqay rownbay oxfay umpedjay veroay
hetay azylay ogday’s ackbay 1234567890 imestay. Hetay azylay ogday umpedjay
veroay hetay uickqay rownbay oxfay’s ackbay 1234567890 imestay. |
|
|
|
|
See part1\unit3\examples\piglatin\piglatin.cpp |
|
|
|
|
|
Input: |
|
The suggestions that follow are meant to broaden
your |
|
awareness of C programming issues that affect
portability, |
|
and to serve as informal guidelines as you write
programs |
|
in C language. These are not rules, but
cautions, for |
|
there is no simple way to develop the skill of |
|
writing portable C programs. Still, if you
remain |
|
aware of these issues and suggestions, you
improve your |
|
chances to write C programs that are portable
from |
|
one UNIX system environment to another, |
|
with little or no need to change the program. |
|
Output: |
|
The
suggestions that follow are meant to broaden
your |
|
awareness of C programming issues
that affect portability, |
|
and to serve as informal guidelines as you write
programs in |
|
C language. These are not rules, but cautions, for there is |
|
no simple
way to develop
the skill of writing portable C |
|
programs.
Still, if you
remain aware of these issues and |
|
suggestions, you improve your chances to write
C programs |
|
that
are portable from
one UNIX system
environment to |
|
another, with little or no need to change the
program. |
|
|
|
|
|
Stage 1 |
|
The |
|
The suggestions |
|
The suggestions that |
|
The suggestions that follow |
|
The suggestions that follow are |
|
|
|
Stage 2 |
|
The suggestions that follow are |
|
The
suggestions that follow are |
|
The
suggestions that follow are |
|
The
suggestions that follow are |
|
|
|
|
Implement the just text justification program |
|
What is a simple algorithm to justify lines of
words? |
|
See detailed instructions at end of chapter |
|
|
|
|
|
This program is useful for VI users! |
|
Justify the next paragraph: |
|
!}just |
|
Justify lines 96-99: |
|
:96,99!just |
|
Justify the next sentence: |
|
:!)just |
|
Justify the current line: |
|
!!just |
|
|
|
|
|
Basic containers |
|
vector |
|
list |
|
deque |
|
Indexed containers |
|
set |
|
map |
|
multiset |
|
multimap |
|
Adaptors |
|
queue |
|
priority_queues |
|
stacks |
|
|
|
|
|
Efficient |
|
Memory |
|
Time |
|
Programmer effort |
|
No Inheritance |
|
No casting |
|
(Fewer) pointers |
|
Extensive use of template feature |
|
|
|
|
#include <algorithm> |
|
… |
|
ostream_iterator<string> out(cout); |
|
*out++ = "abc"; // write “abc” |
|
*out = "xyz"; // write “xyz” |
|
|
|
|
|
|
#include <algorithm> |
|
… |
|
istream_iterator<string> in(cin); |
|
cout << *in; // echo the first word |
|
cout << *in; // echo it again |
|
cout << *++in; // echo the next word |
|
cout << in->length(); /* display the
length */ |
|
|
|
|
|
|
istream_iterator<string> in(cin); |
|
ostream_iterator<string> out(cout); |
|
istream_iterator<string> end; |
|
int len=0; |
|
while(in != end){ |
|
*out++
= *in++; |
|
if((len
+= in->length()) > 30){ |
|
len =
0; |
|
*out++ = "\n"; |
|
} |
|
else{ |
|
*out++ = " "; |
|
} |
|
} |
|
|
|
|
|
vector<string> x(1000); |
|
//list<string> x; |
|
//string x[1000]; |
|
istream_iterator<string> in(cin), end; |
|
ostream_iterator<string> out(cout); |
|
copy(in, end, x.begin()); |
|
|
|
/*
This does the same thing |
|
{ |
|
string word; |
|
while(cin >> word) |
|
x.push_back(word); |
|
} */ |
|
|
|
|
|
vector<string> x(1000); |
|
//list<string> x; |
|
//string x[1000]; |
|
|
|
copy(
istream_iterator<string>(cin), istream_iterator<string>(),
x.begin()); |
|
|
|
|
|
//vector<string> x(1000); |
|
//list<string> x; |
|
string x[1000]; |
|
|
|
copy(
istream_iterator<string>(cin), istream_iterator<string>(), x); |
|
|
|
|
|
//vector<string> y(1000); |
|
list<string> y; |
|
//string y[1000]; |
|
|
|
copy(y.begin(), y.end(),
ostream_iterator<string>(cout, " ")); |
|
|
|
/*
This does the same thing |
|
{ |
|
for(list<string>::iterator ii = y.begin(); ii != y.end();
ii++) |
|
cout
<< *ii << " " << endl; |
|
} */ |
|
|
|
|
|
sort(array.begin(), array.end()); |
|
|
|
copy(array.begin(),
array.end(), ostream_iterator<string>(cout, "\n")); |
|
|
|
/* This does the same thing |
|
for(vector<string>::iterator ii =
array.begin(); ii != array.end(); ii++) |
|
cout << *ii << endl; |
|
*/ |
|
return 0; |
|
} |
|
|
|
|
|
|
|
Interchangable |
|
Lists |
|
Deques |
|
C++ arrays (vectors) |
|
C arrays |
|
All define member functions |
|
insert |
|
push_back |
|
push_front |
|
pop_front |
|
pop_back |
|
|
|
|
|
Double ended queue! |
|
In the standard library, a deque is |
|
Optimized differently |
|
Cross between array (contiguous) and List (one
element per node) |
|
A linked list of arrays |
|
Deques |
|
Have multiple array elements per node |
|
Special allocation strategy |
|
What is the problem with inserting a new element
at the beginning of an array? |
|
|
|
|
|
|
|
Sets have items |
|
An item can occur only once |
|
Examples of infinite sets |
|
All integers |
|
All reals |
|
Examples of finite sets in C++ |
|
Persons working for AT&T |
|
Satellites |
|
Departments at AT&T |
|
|
|
|
|
Complete value semantics |
|
Declaration: set<string> persons, leaders; |
|
Operations |
|
swap |
|
upper_bound |
|
lower_bound |
|
count |
|
erase |
|
empty |
|
insert |
|
clear |
|
|
|
|
|
#include <fstream> |
|
#include <iostream> |
|
#include <set> |
|
#include <string> |
|
const int nWords = 63; |
|
string data[] = {"C",
"Still,",…}; |
|
main(){ |
|
set<string> dict(data, data+nWords); |
|
string
word; |
|
while(cin >> word){ |
|
if
(dict.find(word) == dict.end()) |
|
cout
<< "Misspelled word: " << word << endl; |
|
} |
|
return
0; |
|
} |
|
|
|
|
Work in part1\unit3\exercise\emptab |
|
Use class set to rewrite part1\unit1\solution\array2\emptab.cpp |
|
Strategy: Use 3 set variables: ito, sdp, mm |
|
|
|
|
|
main(){ |
|
set<string> ito, mm, sdp; |
|
|
|
|
|
|
|
//
Prompt name and search table |
|
string
name; |
|
while(cout << "Enter name: ", cin >>
name) { |
|
|
|
|
|
|
|
|
|
} //
while |
|
return
0; |
|
} // main |
|
|
|
|
|
Previous approach |
|
Efficient? |
|
Elegant? |
|
Improvements? |
|
How about a two column table? |
|
Can this be done with class set? |
|
|
|
|
|
Define the format single row of the table |
|
struct Emp { string name, dept; }; |
|
bool operator == (const Emp& a, const
Emp& b){ return a.name == b.name; } |
|
bool operator > (const Emp& a, const
Emp& b)
{ return a.name > b.name; } |
|
main(){ |
|
Define the table |
|
set<Emp> emptab; |
|
Define a single row |
|
Emp
emp; |
|
|
|
|
|
Populate the table |
|
emp.name = "Joe"; emp.dept =
"MM"; emptab += emp; |
|
emp.name = "John"; emp.dept =
"ITO"; emptab += emp;… |
|
Loop and prompt |
|
while(cout << "Enter name: ", cin >> emp.name) |
|
if(emptab.find(emp)!=emptab.end()) |
|
cout << "dept = " << emp.dept; |
|
else |
|
cout << |
|
"Corporate Spy, Call Security!"; |
|
return
0; |
|
} |
|
|
|
|
This approach works |
|
It is clumsy but efficient |
|
Is there a better way yet? |
|
|
|
|
|
Lookup table |
|
Key-value pairs |
|
Map keys to values |
|
Many names |
|
Associative array |
|
Map |
|
Dictionary |
|
Complete value semantics |
|
Operations called by class user |
|
Map key to values (subscript) |
|
Count key-value pairs |
|
Fetch the first, next, previous or last key |
|
|
|
|
|
map<string,int> m; |
|
m["hello"]++; m["world"]++;
m["world"]++; |
|
|
|
|
|
Declarations with templates |
|
#include <string> |
|
#include <map> |
|
using namespace std; |
|
map<string, int> m; |
|
map<int, string> mapis; |
|
map<float,string>mapfs; |
|
map<string,string>mapss; // same as below |
|
//map<string,string,less<string> >
mapss; |
|
|
|
|
|
Subscripts |
|
string key = "hello"; |
|
m[key] = 3; // store 3 |
|
m[key]++; // update 4 |
|
m["world"] = m[key]; // fetch and
store |
|
m[key] = m[key] + 2; // 6 |
|
Element counts |
|
int i = m.size(); // i = 2 |
|
|
|
|
|
Keys |
|
(*m.begin()).first; // first key |
|
(*--(m.end())).first; // last key |
|
(*++(m.begin())).first; // second key |
|
Traversal and output |
|
map<string,int,less<string>
>::iterator i; |
|
for(i = m.begin(); i != m.end(); i++) |
|
cout
<< i->first << "\t" << (*i).second <<
endl; |
|
|
|
|
|
Assignment |
|
map<string,int> map2; |
|
map2 = m; |
|
Pass by value and return by value |
|
void save(map<string,int> m); |
|
map<string,int> restore(); |
|
... |
|
save(map); |
|
... |
|
map2 = restore(); |
|
|
|
|
|
Input |
|
The suggestions that follow are meant to broaden
your |
|
awareness of C programming issues that affect
portability, |
|
and to serve as informal guidelines as you write
programs |
|
in C language. These are not rules, but
cautions, for |
|
there is no simple way to develop the skill of |
|
writing portable C programs. Still, if you
remain |
|
aware of these issues and suggestions, you
improve your |
|
chances to write C programs that are portable
from |
|
one UNIX system environment to another, |
|
with little or no need to change the program. |
|
Output |
|
C: 4 |
|
Still,: 1 |
|
The: 1 |
|
These: 1 |
|
UNIX: 1 |
|
affect: 1 |
|
and: 2 |
|
another,: 1 |
|
... |
|
|
|
|
|
main(){ |
|
typedef
std::map<std::string,int, std::less<std::string> > map; |
|
map m; |
|
string
word; |
|
while
(cin >> word) |
|
m[word]++; |
|
for
(map::iterator ii = m.begin();
ii != m.end(); ii++) |
|
cout
<< ii->first << ": " <<
ii->second << endl; |
|
return
0; |
|
} |
|
|
|
|
Work in part1\unit3\ exercise\emptab2 |
|
Use class map to rewrite part1\unit1\
solution\array2\ emptab.cpp |
|
Strategy: Use one map for a single two column
table |
|
|
|
|
|
main(){ |
|
|
|
|
|
|
|
|
|
//
Prompt name and search table |
|
string
name; |
|
while(cout << "Enter name: ", cin >> name) |
|
if(
) |
|
|
|
|
|
|
|
else cout << "Corporate Spy, Call Security!"; |
|
} |
|
|
|
|
|
|
|
How can we have multi-column tables? |
|
A table of employees that tells us SSN, salary,
department? |
|
A table of ingredients and suppliers? |
|
A table of products and customers? |
|
A table of ingredients? |
|
|
|
|
|
Like C-Style array |
|
Bounds checking |
|
Only with member function at |
|
Does not work with [] |
|
Value semantics |
|
Subscripts |
|
Fetch |
|
Store |
|
Update |
|
|
|
|
|
Method 1 |
|
vector<string> name(1,10); |
|
name[j] = "hello"; |
|
Method 2 |
|
map<int,string> name; |
|
name[j] = "hello"; |
|
|
|
|
|
Declaration |
|
#include <string> |
|
#include <vector> |
|
vector<string> array(1,20); |
|
Subscript |
|
string tmp; |
|
tmp = array[i]; |
|
array[i] = array[i+1] |
|
array[i+1] = tmp; |
|
Element count |
|
int size = array.size(); |
|
|
|
|
|
Assignment |
|
vector<string> a2; |
|
a2 = array; |
|
Pass by value |
|
void save(vector<string> a); |
|
... save(array); |
|
Return by value |
|
vector<string> restore(); |
|
array = restore(); |
|
|
|
|
|
vector<string> y(1000); |
|
|
|
copy(y.begin(), y.end(),
ostream_iterator<string>(cout, " ")); |
|
|
|
/*
This does the same thing |
|
{ |
|
for(vector<string>::iterator ii = y.begin(); ii != y.end();
ii++) |
|
cout
<< *ii << " " << endl; |
|
} */ |
|
|
|
|
|
|
|
#include <algorithm> |
|
using namespace std; |
|
main(){ |
|
vector<string> array(1000); |
|
{ |
|
istream_iterator<string> in(cin); |
|
istream_iterator<string> end; |
|
copy(in, end, array.begin()); |
|
} |
|
sort(array.begin(), array.end()); |
|
copy(array.begin(), array.end(),
ostream_iterator<string>(cout, "\n")); |
|
return
0; |
|
} |
|
|
|
|
|
|
#include <fstream> |
|
#include <iostream> |
|
#include <string> |
|
#include <set> |
|
#include <algorithm> |
|
using namespace std; |
|
main(){ |
|
multiset<string> s; |
|
copy(istream_iterator<string>(cin),
istream_iterator<string>(), inserter(s, s.begin())); |
|
copy(s.begin(), s.end(), ostream_iterator<string>(cout,
"\n")); |
|
return
0; |
|
} |
|
|
|
|
#include <fstream> |
|
#include <iostream> |
|
#include <string> |
|
#include <set> |
|
#include <algorithm> |
|
using namespace std; |
|
main(){ |
|
set<string> s; |
|
copy(istream_iterator<string>(cin),
istream_iterator<string>(), inserter(s, s.begin())); |
|
copy(s.begin(), s.end(), ostream_iterator<string>(cout,
"\n")); |
|
return
0; |
|
} |
|
|
|
|
|
Suppose C++ style array is implemented with
C-style array? |
|
Could the class provider add a member function
to grow or shrink the array? |
|
What might be a problem with this? (See next
slide) |
|
|
|
|
vector<int> v(1); |
|
v[0] =
22; |
|
int* p
= &v[0]; |
|
vector<int>::iterator it = v.begin(); |
|
cout
<< *p << endl; |
|
cout
<< *it << endl; |
|
v.push_back(32); |
|
v.push_back(33); |
|
v.push_back(34); |
|
cout
<< *p << endl; |
|
cout
<< *it << endl; |
|
copy(v.begin(), v.end(),
ostream_iterator<int>(cout," ")); |
|
|
|
|
|
|
Types and user-defined types |
|
The standard library |
|
Name spaces |
|
Class user programming with templates |
|
Basic containers & iterators |
|
list stacks, strings, vectors, maps & sets |
|
Special iterators for I/O |
|
Examples of reusing software components |
|
Calculator — stack type |
|
Text justification — string type |
|
Employee Security & Spell Checking — set
type |
|
Count unique words — map type |
|
Sorting a list of words — map type |
|
|
|
|
|
|
|
|
|
Solution #1: Store cents, not dollars! |
|
Simple |
|
Won’t help for interest calculations! |
|
Solution #2: Perform rounding before display |
|
Simple |
|
Works for trivial calculations |
|
Round-off will eventually get you |
|
Solution #3: Use Binary Coded Decimal (BCD) |
|
Difficult implementation |
|
Calculations are done in base 10 |
|
1/5 is no longer a repeating fraction |
|
|
|
|
|
Picture variables implement |
|
BCD |
|
Special formatting for business applications |
|
Class Exercise: |
|
For what radix (base) is + - / * defined in C? |
|
How do we perform BCD arithmetic? |
|
Can we use + - / * in C for BCD arithmetic? |
|
|
|
|
|
COBOL |
|
77 PAY-CHECK-AMOUNT, PICTURE $***,*99.99. |
|
MOVE 1679.02 TO PAY-CHECK-AMOUNT. |
|
PL/I |
|
DECLARE PAY_CHECK_AMOUNT PIC ‘$***,*99.99’; |
|
PAY_CHECK_AMOUNT = 16769.02; |
|
C++ |
|
#include “Picture.h” |
|
Picture payCheckAmount(“$***,*99.99”); |
|
payCheckAmount = 1679.02; |
|
cout << payCheckAmount; |
|
Output |
|
$**1,679.02 |
|
|
|
|
|
Similar features to PL/I and COBOL |
|
Full value semantics |
|
Operations |
|
Print (operator<<) |
|
Add, substract, multiply and divide |
|
Assign numeric values |
|
|
|
|
|
Write a program to print the following: |
|
hourly rate: $62.65 |
|
hours worked: 040 |
|
tax rate: 0.33 |
|
gross pay: $2,506.00 |
|
income tax: $826.98 |
|
pay check amount: $**1,679.02 |
|
|
|
|
#include <iostream.h> |
|
#include "Picture.h" |
|
|
|
main(){ |
|
Picture hourlyRate("$$99.99"); |
|
hourlyRate = 62.65; |
|
cout << "hourly rate: " << hourlyRate <<
'\n'; |
|
|
|
Picture hoursWorked("999"); |
|
hoursWorked = 40; |
|
cout << "hours worked: "
<< hoursWorked << '\n'; |
|
|
|
Picture taxRate("9.99"); |
|
taxRate = .33; |
|
cout << "tax rate: " << taxRate <<
'\n'; |
|
|
|
|
Picture grossPay("$$$$,$99.99"); |
|
grossPay = hourlyRate * hoursWorked; |
|
cout << "gross pay: " << grossPay <<
'\n'; |
|
|
|
Picture incomeTax("$$$$,$99.99"); |
|
incomeTax = grossPay * taxRate; |
|
cout << "income tax: " << incomeTax << '\n'; |
|
|
|
Picture
payCheckAmount("$***,*99.99"); |
|
payCheckAmount = grossPay - incomeTax; |
|
cout << "amount:" <<
payCheckAmount << '\n'; |
|
return 0; |
|
} |
|
|
|
|
Additional Laboratory Exercise |
|
|
|
|
|
|
Work in part1\unit3\exercise\toc or part1\unit3\exercise\nt-toc. |
|
Write a file lister program. |
|
Fetch file names from command line. |
|
Copy files, line by line, to output. |
|
Paginate output. |
|
Generate table-of-contents at end. |
|
list each file name. |
|
list page number each file starts on. |
|
Additional features to add: |
|
Headers and footers with titles and page
numbers. |
|
Left, right, top and bottom margins. |
|
Accomodation of long lines. (Wrap them). |
|
|
|
|
|
Example of desired output: |
|
toc \labs\include\*.h |
|
\labs\include\NODE.H |
|
-----------------------------------------\labs\include\NODE.H |
|
... |
|
-------------------------------------\labs\include\MAPTYP1T.H |
|
... |
|
page 1 |
|
\labs\include\MAPTYP1T.H |
|
... |
|
Table of Contents |
|
\labs\include\NODE.H 1 |
|
\labs\include\MAPTYP1T.H 1 |
|
\labs\include\MAP.H 63 |
|
\labs\include\LINKEDLI.H 129 |
|
... |
|
page 1 |
|
|
|
|
|
Use map<string,int> to store toc (table of
contents). |
|
Read entire lines with |
|
char buf[MAX]; |
|
while(cin.getline(buf, MAX)){ |
|
string line = buf; |
|
line = line.detab(); ... } |
|
Use constants defined in toc.h |
|
const nMARGIN = 8; // left and right margins |
|
const nWIDTH = 80; // page width |
|
const nLPP = 66; // lines per page |
|
const nHEAD = 5; // top margin |
|
const nTRAIL = 5; // bottom margin |
|
const MAXLINE = 2048; // maximum length of line |
|
|
|
|
|
Use standard I/O manipulators. |
|
setw(int)
// set field width |
|
setfill(char) // set fill character |
|
Use custom I/O manipulators (Templates only) |
|
cout<<left; cout << right;// left
and right justify |
|
// output footer |
|
cout << footer(nPage, nLine, "Page
"); |
|
// output header |
|
cout << header(nPage, nLine, "Header
Text"); |
|
// output header and footer |
|
// if
at bottom of page |
|
cout << newLine(nPage, nLine, "Header
Text"); |
|
cout << vspace(6); // out 6 blank lines |
|
cout << hspace(3); // output 3 blanks |
|
|
|
|
|
Substitutes for I/O manipulators. |
|
// Output footer |
|
footer(cout, nPage, nLine, "Page"); |
|
// Output header |
|
header(cout, filename); |
|
// Output ‘\n’ and header and footer |
|
// if
at bottom of page |
|
newLine(cout, nPage, nLine, filename); |
|
// Output six horizontal spaces |
|
hspace(cout, 6); |
|
// Output 3 vertical spaces |
|
vspace(cout, 3); |
|