|
Objektorientiertes Programmieren mit C++ und JAVA
|
|  
|
14.9 Beispiel
|  
|
Mit dem folgenden Programm killtab kann man explizit vorhandene
Tabulartorcodes aus Textdateien entfernen, d.h. durch passend viele
Spaces ersetzen (gleich breite Spalten vorausgesetzt). Das Programm erhält
die Namen der Eingabe- und Ausgabedatei sowie die gewünschte
Tabulatorbreite über die Aufrufzeile. Die Namen können (in der
Reihenfolge Eingabe, Ausgabe) direkt oder mit den Optionen -i bzw.
-o angegeben werden, voreingestellt sind Standardeingabe und -ausgabe.
Wird die Breitenangabe (mit -w) weggelassen, wird 8 benutzt.
Wenn aus echten Dateien gelesen wird, müssen die Klassen ifstream
und ofstream benutzt werden, dagegen sind Standardein- und -ausgabe
von den Typen istream_withassign bzw. ostream_withassign.
Wir benutzen daher ein Unterprogramm killtabs, das Referenzen
auf istream bzw. ostream übergeben bekommt, von denen die
anderen Typen ja abgeleitet sind (und mit deren Ein- und Ausgabeoperationen
wir ja auskommen).
Im Hauptprogramm arbeiten wir dagegen mit Pointern auf
ifstream bzw. ofstream, die 0 sind, wenn kein entsprechender
Name in der Aufrufzeile angegeben wurde. (Undefinierte Referenzen gibt
es ja nicht.)
Die Breitenangabe in ASCII-Zeichen aus der Aufrufzeile müssen wir
natürlich noch in eine int-Zahl umwandeln. Dafür
würde man normalerweise eine Funktion wie atoi verwenden. Zu
Demonstrationszwecken setzen wir hier aber die Klasse istrstream ein.
- #include <iostream.h>
#include <fstream.h>
#include <strstream.h>
#include <stdlib.h>
#include <ctype.h>
void Usage()
{
cerr << "Usage: killtab -i infile -o outfile [-w width]\n";
cerr << " killtab [infile] [outfile] [-w width]\n";
exit(10);
}
void killtabs(istream &in, ostream &out, int w)
{
int x=0;
char c;
while (in.get(c))
{
if (c=='\t')
for (x=w-(x%w);x>0;--x) out.put(' ');
else
{
out.put(c);
if (c=='\n') x=0;
else ++x;
}
}
}
void main(int argc, char *argv[])
{
char *inname=0,*outname=0;
istream *infile=0;
ostream *outfile=0;
int width=-1;
for (int i=1;i<argc;++i)
{
char opt;
char *par=argv[i];
if (par[0]=='-' && (opt=tolower(par[1]))!=0)
{
if (par[2]==0)
{
if (++i==argc) Usage();
par=argv[i];
}
else par+=2;
switch (opt)
{
case 'i':
if (inname!=0) Usage();
inname=par;
break;
case 'o':
if (outname!=0) Usage();
outname=par;
break;
case 'w':
if (width>0) Usage();
{
istrstream itmp(par);
itmp >> width;
if (!itmp || width<=0) Usage();
}
break;
default: Usage();
}
}
else if (inname==0) inname=par;
else if (outname==0) outname=par;
else Usage();
}
if (width<=0) width=8;
if (inname && !*(infile=new ifstream(inname)))
{ cerr << "can't open " << inname << endl; return 10; }
if (outname && !*(outfile=new ofstream(outname)))
{ cerr << "can't open " << outname << endl; return 10; }
killtabs(infile?*infile:cin,outfile?*outfile:cout,width);
if (infile) delete infile;
if (outfile) delete outfile;
}