implement fixed width printing
This commit is contained in:
@ -19,15 +19,15 @@
|
|||||||
#include "lib/OutStream.h"
|
#include "lib/OutStream.h"
|
||||||
|
|
||||||
class CGA_Stream : public OutStream, public CGA {
|
class CGA_Stream : public OutStream, public CGA {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGA_Stream(CGA_Stream ©); // Verhindere Kopieren
|
CGA_Stream(CGA_Stream ©); // Verhindere Kopieren
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGA_Stream () : OutStream(), CGA() { flush(); }
|
CGA_Stream () : OutStream(), CGA() { flush(); }
|
||||||
|
|
||||||
// Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer.
|
// Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer.
|
||||||
virtual void flush ();
|
void flush () override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -22,15 +22,64 @@
|
|||||||
|
|
||||||
#include "lib/OutStream.h"
|
#include "lib/OutStream.h"
|
||||||
|
|
||||||
|
// NOTE: I added this, stream manipulators with arg
|
||||||
|
OutStream& OutStream::operator << (const fillw& w) {
|
||||||
|
this->fill_width = w.w;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
OutStream& OutStream::operator << (const fillc& c) {
|
||||||
|
this->fill_char = c.c;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: I added this, fixed width printing
|
||||||
|
void OutStream::put(char c) {
|
||||||
|
if (this->fill_width == 0) {
|
||||||
|
StringBuffer::put(c);
|
||||||
|
} else if (this->fill_used == this->fill_width - 1) {
|
||||||
|
// This indicates that content has been cut
|
||||||
|
StringBuffer::put('@');
|
||||||
|
this->fill_use_char();
|
||||||
|
} else if (this->fill_used == this->fill_width) {
|
||||||
|
// do nothing
|
||||||
|
} else {
|
||||||
|
StringBuffer::put(c);
|
||||||
|
this->fill_use_char();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void OutStream::fill_finalize() {
|
||||||
|
if (this->fill_width == 0 || this->fill_used == this->fill_width) {
|
||||||
|
// do nothing
|
||||||
|
} else if (this->fill_used > this->fill_width) {
|
||||||
|
// should never happen
|
||||||
|
} else {
|
||||||
|
for (unsigned char i = 0; i < this->fill_width - this->fill_used; ++i) {
|
||||||
|
StringBuffer::put(this->fill_char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->fill_used = 0;
|
||||||
|
}
|
||||||
|
void OutStream::fill_use_char() {
|
||||||
|
if (this->fill_width == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->fill_used++;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Zeichen und Zeichenketten in Stream ausgeben
|
// Zeichen und Zeichenketten in Stream ausgeben
|
||||||
//
|
//
|
||||||
OutStream& OutStream::operator << (char c) {
|
OutStream& OutStream::operator << (char c) {
|
||||||
put(c);
|
put(c);
|
||||||
|
if (c != '\n') {
|
||||||
|
// endl() doesn't has access to StringBuffer::put(), so ignore \n here
|
||||||
|
this->fill_finalize(); // NOTE: I added this
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: shouldn't this be printed as number?
|
||||||
OutStream& OutStream::operator << (unsigned char c) {
|
OutStream& OutStream::operator << (unsigned char c) {
|
||||||
return *this << (char) c;
|
return *this << (char) c;
|
||||||
}
|
}
|
||||||
@ -41,6 +90,7 @@ OutStream& OutStream::operator << (char* string) {
|
|||||||
put (*pos);
|
put (*pos);
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
this->fill_finalize(); // NOTE: I added this
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,10 +129,10 @@ OutStream& OutStream::operator << (long ival) {
|
|||||||
OutStream& OutStream::operator << (unsigned long ival) {
|
OutStream& OutStream::operator << (unsigned long ival) {
|
||||||
unsigned long div;
|
unsigned long div;
|
||||||
char digit;
|
char digit;
|
||||||
|
|
||||||
if (base == 8)
|
if (base == 8) {
|
||||||
put ('0'); // oktale Zahlen erhalten eine fuehrende Null
|
put ('0'); // oktale Zahlen erhalten eine fuehrende Null
|
||||||
else if (base == 16) {
|
} else if (base == 16) {
|
||||||
put ('0'); // hexadezimale Zahlen ein "0x"
|
put ('0'); // hexadezimale Zahlen ein "0x"
|
||||||
put ('x');
|
put ('x');
|
||||||
}
|
}
|
||||||
@ -94,12 +144,14 @@ OutStream& OutStream::operator << (unsigned long ival) {
|
|||||||
// ziffernweise Ausgabe der Zahl
|
// ziffernweise Ausgabe der Zahl
|
||||||
for (; div > 0; div /= (unsigned long) base) {
|
for (; div > 0; div /= (unsigned long) base) {
|
||||||
digit = ival / div;
|
digit = ival / div;
|
||||||
if (digit < 10)
|
if (digit < 10) {
|
||||||
put ('0' + digit);
|
put ('0' + digit);
|
||||||
else
|
} else {
|
||||||
put ('a' + digit - 10);
|
put ('a' + digit - 10);
|
||||||
|
}
|
||||||
ival %= div;
|
ival %= div;
|
||||||
}
|
}
|
||||||
|
this->fill_finalize(); // NOTE: I added this
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +182,7 @@ OutStream& OutStream::operator << (OutStream& (*f) (OutStream&)) {
|
|||||||
// Fuege einen Zeilenumbruch in die Ausgabe ein.
|
// Fuege einen Zeilenumbruch in die Ausgabe ein.
|
||||||
OutStream& endl (OutStream& os) {
|
OutStream& endl (OutStream& os) {
|
||||||
os << '\n';
|
os << '\n';
|
||||||
os.flush ();
|
os.flush();
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,13 +7,13 @@
|
|||||||
* << Operators fuer die wichtigsten der vordefinierten *
|
* << Operators fuer die wichtigsten der vordefinierten *
|
||||||
* Datentypen und realisiert somit die bekannte Ausgabe- *
|
* Datentypen und realisiert somit die bekannte Ausgabe- *
|
||||||
* funktion der C++ iO_Stream Bibliothek. Zur Zeit wird *
|
* funktion der C++ iO_Stream Bibliothek. Zur Zeit wird *
|
||||||
* die Darstellung von Zeichen, Zeichenketten und ganzen *
|
* die Darstellung von Zeichen, Zeichenketten und ganzen *
|
||||||
* Zahlen unterstuetzt. Ein weiterer << Operator erlaubt *
|
* Zahlen unterstuetzt. Ein weiterer << Operator erlaubt *
|
||||||
* die Verwendung von Manipulatoren. *
|
* die Verwendung von Manipulatoren. *
|
||||||
* *
|
* *
|
||||||
* Neben der Klasse OutStream sind hier auch die *
|
* Neben der Klasse OutStream sind hier auch die *
|
||||||
* Manipulatoren hex, dec, oct und bin fuer die Wahl der *
|
* Manipulatoren hex, dec, oct und bin fuer die Wahl der *
|
||||||
* Basis bei der Zahlendarstellung, sowie endl fuer den *
|
* Basis bei der Zahlendarstellung, sowie endl fuer den *
|
||||||
* Zeilenumbruch definiert. *
|
* Zeilenumbruch definiert. *
|
||||||
* *
|
* *
|
||||||
* Autor: Olaf Spinczyk, TU Dortmund *
|
* Autor: Olaf Spinczyk, TU Dortmund *
|
||||||
@ -24,17 +24,51 @@
|
|||||||
|
|
||||||
#include "lib/StringBuffer.h"
|
#include "lib/StringBuffer.h"
|
||||||
|
|
||||||
|
// NOTE: I added this, stream manipulator with argument
|
||||||
|
class OutStream;
|
||||||
|
|
||||||
|
// TODO: Should this only work for the next << ?
|
||||||
|
class fillw {
|
||||||
|
public:
|
||||||
|
fillw(unsigned char w) : w(w) {};
|
||||||
|
unsigned char w;
|
||||||
|
};
|
||||||
|
|
||||||
|
class fillc {
|
||||||
|
public:
|
||||||
|
fillc(char c) : c(c) {};
|
||||||
|
char c;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class OutStream : public StringBuffer {
|
class OutStream : public StringBuffer {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OutStream(const OutStream ©); // Verhindere Kopieren
|
OutStream(const OutStream ©); // Verhindere Kopieren
|
||||||
|
|
||||||
|
// NOTE: I added this
|
||||||
|
unsigned char fill_used; // indicates how many characters are already used by the text internally
|
||||||
|
void fill_use_char(); // recognizes that one char from the print width has been used up
|
||||||
|
void fill_finalize(); // does the filling after text has been written to buffer
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int base; // Basis des Zahlensystems: z.B. 2, 8, 10 oder 16
|
int base; // Basis des Zahlensystems: z.B. 2, 8, 10 oder 16
|
||||||
|
|
||||||
OutStream () : StringBuffer () { base = 10; } // initial Dezimalsystem
|
// NOTE: I added this
|
||||||
|
unsigned char fill_width;
|
||||||
|
char fill_char; // fill character for fixed width
|
||||||
|
|
||||||
virtual void flush () = 0; // weiterhin undefiniert
|
OutStream () : StringBuffer () {
|
||||||
|
base = 10; // initial Dezimalsystem
|
||||||
|
fill_width = 0; // no fixed width
|
||||||
|
fill_used = 0;
|
||||||
|
fill_char = ' '; // fill with spaces
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush() override = 0; // weiterhin undefiniert aber public
|
||||||
|
|
||||||
|
// NOTE: I added this
|
||||||
|
void put(char c) override;
|
||||||
|
|
||||||
// OPERATOR << : Umwandlung des angegebenen Datentypes in eine
|
// OPERATOR << : Umwandlung des angegebenen Datentypes in eine
|
||||||
// Zeichenkette.
|
// Zeichenkette.
|
||||||
@ -57,9 +91,12 @@ public:
|
|||||||
// Darstellung eines Zeigers als hexadezimale ganze Zahl
|
// Darstellung eines Zeigers als hexadezimale ganze Zahl
|
||||||
OutStream& operator << (void* ptr);
|
OutStream& operator << (void* ptr);
|
||||||
|
|
||||||
|
// NOTE: I added this, set fixed output width
|
||||||
|
OutStream &operator << (const fillw &w);
|
||||||
|
OutStream &operator << (const fillc &c);
|
||||||
|
|
||||||
// Aufruf einer Manipulatorfunktion
|
// Aufruf einer Manipulatorfunktion
|
||||||
OutStream& operator << (OutStream& (*f) (OutStream&));
|
OutStream& operator << (OutStream& (*f) (OutStream&));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -36,8 +36,9 @@ protected:
|
|||||||
// StringBuffer: Im Konstruktor wird der Puffer als leer markiert.
|
// StringBuffer: Im Konstruktor wird der Puffer als leer markiert.
|
||||||
StringBuffer () : pos(0) {}
|
StringBuffer () : pos(0) {}
|
||||||
|
|
||||||
|
// NOTE: I changed this
|
||||||
// Fuegt ein Zeichen in den Puffer ein. Wenn der Puffer
|
// Fuegt ein Zeichen in den Puffer ein. Wenn der Puffer
|
||||||
void put (char c);
|
virtual void put (char c);
|
||||||
|
|
||||||
// Methode zur Ausgabe des Pufferinhalts
|
// Methode zur Ausgabe des Pufferinhalts
|
||||||
virtual void flush () = 0;
|
virtual void flush () = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user