Documentos de Académico
Documentos de Profesional
Documentos de Cultura
by Bruce Eckel
[LISTING ONE]
struct item {
virtual ~item() {} // so collection can properly destroy what it holds
};
#ifdef TEST1
main() {
collection c;
for(int i = 0; i < sizeof(words)/sizeof(words[0]); i++)
c.add(new worditem(words[i]));
// NOTE: Zortech C++ 2.06 doesn't work here.
}
#endif // TEST1
#ifdef TEST2
main() {
wordcounter wc;
for(int i = 0; i < sizeof(words2)/sizeof(words2[0]); i++)
wc.add_or_count(words2[i]);
// Now "apply" two different functions to the list:
wc.apply(&word::print1);
wc.apply(&word::print2); putchar('\n');
}
#endif // TEST2
// Now, for fun, let's use this class to count the keywords and
// identifiers in a C++ program. Try this program on itself:
// collect < collect.cpp > count
// Look up strstr(), strchr() and strtok() in your ANSI C
// library guide.
#ifdef TEST3
main() { // use i/o redirection on the command line.
wordcounter symbol_table;
char buf[120];
while (gets(buf)) { // get from standard input
if(*buf == '#') continue; // ignore preprocessor lines
// strip all quoted strings in the line:
char * quote = strchr(buf, '\"'); // find first quoted string
while(quote) {
if(quote[-1] == '\\') break; // for \" literal quote
*quote++ = ' '; // erase quote
while(*quote != '\"' && *quote != 0)
*quote++ = ' '; // erase contents of string
*quote = ' '; // erase ending quote
quote = strchr(quote, '\"'); // look for next quoted string
}
char * cmt = strstr(buf, "//"); // C++-style comments only
if(cmt) *cmt = 0; // strip comments by terminating string
puts(buf); // Look at the modified string
char * token; // strtok uses delimiters to find a token:
if((token = strtok(buf, delimiters)) != NULL){ // first strtok call
if(strcspn(token, digits)) // ignore constants
symbol_table.add_or_count(token);
// subsequent strtok calls for the same input line:
while((token = strtok(0, delimiters)) != NULL)
if(strcspn(token, digits)) // ignore constants
symbol_table.add_or_count(token);
}
} // print the list in 2 ways, using pointers to members:
symbol_table.apply(&word::print1);
symbol_table.apply(&word::print2); putchar('\n');
} // results are output by the destructor calls
#endif // TEST3
macro InsertVoid
SetMark(0); /* save our place */
LeftOfLine;
InsertText("void ");
MoveToMark(0); /* restore the place */
end; /* end of macro InsertVoid */
item * i = c.reset();
while(i) {
// do something
i = c.next();
}