N
So, ich hab jetzt mal einen eigenen Algorithmus geschrieben. Das mit den mehreren Leerzeichen hab ich zwar nicht hingekriegt, stattdessen werden sie rausgefiltert, aber das mit dem Bindestrich und das mit den zu langen Wörtern funktioniert. Wenn Euch noch Fehler auffallen, sagt mir bitte bescheid.
(Unten steht der Code nochmal ohne Kommentare.)
//Diese Funktion ersetzt alle Vorkommen des alten Strings mit dem neuen.
void Ersetzen (string &text, const string &alterText, const string &neuerText)
{
UINT pos;
do
{
pos=text.find (alterText);
if (pos!=string::npos)
text.replace (pos, alterText.length (), neuerText);
}
while (pos!=string::npos);
}
void TextUmbrechen (string &text, UINT &zeilenlaenge)
{
if (zeilenlaenge!=0)
{
//Alle doppelten Leerzeichen und Leerzeichen vor Absätzen
//werden gelöscht.
Ersetzen (text, " ", " ");
Ersetzen (text, " \n", "\n");
//Feld für die einzelnen Wörter
vector<string> feld (1);
//Zählervariable für später
int n;
//Teil 1: Aufteilen des Textes
//----------------------------
for (int i=0; i<text.length (); i++)
{
string &wort=feld [feld.size ()-1];
char &zeichen=text [i];
//Dem aktuellen Feldeintrag wird ein Zeichen hinzugefügt
wort+=zeichen;
//Wenn es ein Umbruchszeichen ist oder wenn die Zeilenlänge erreicht ist,
if (zeichen=='\n' || zeichen==' ' || zeichen=='-' || wort.length ()==zeilenlaenge)
feld.push_back ("");
//wird ein neuer Feldeintrag erstellt.
}
text.erase ();
//Teil 2: Wiederzusammensetzen des Textes
//---------------------------------------
//Das n stellt den verbleibenden Platz einer Zeile dar.
n=zeilenlaenge;
for (i=0; i<feld.size (); i++)
{
string &wort=feld [i];
char &letztesZeichen=wort [wort.length ()-1];
//Für die Frage, ob in der Zeile noch genug Platz ist,
//wird das letzte Zeichen, wenn es ein Absatzzeichen
//oder ein Leerzeichen ist, nicht mitgezählt
int laenge=wort.length ()-(letztesZeichen=='\n' || letztesZeichen==' '?1:0);
//Wenn noch Platz ist (Whitespacezeichen nicht mitgezählt),
if (laenge<=n)
{
//wird das Wort hinzugefügt.
text+=wort;
//und die Anzahl der Zeichen (diesmal mit
//Whitespacezeichen) abgezogen.
n-=wort.length ();
//Wenn das letzte Zeichen ein \n war, haben wir ohnehin
//eine neue Zeile und n wird wieder auf den Maximalwert
//gesetzt.
if (letztesZeichen=='\n')
n=zeilenlaenge;
}
else
{
//Wenn kein Platz mehr war, wird eine neue Zeile begonnen.
text+='\n';
n=zeilenlaenge;
//i wird um eins zurückgesetzt, damit im nächsten Durchlauf
//das Wort, das hier nicht mehr gepaßt hat, bearbeitet wird.
i--;
}
}
//Zum Schluß eine weitere Ersetzung.
Ersetzen (text, " \n", "\n");
}
}
void Ersetzen (string &text, const string &alterText, const string &neuerText)
{
UINT pos;
do
{
pos=text.find (alterText);
if (pos!=string::npos)
text.replace (pos, alterText.length (), neuerText);
}
while (pos!=string::npos);
}
void TextUmbrechen (string &text, UINT &zeilenlaenge)
{
if (zeilenlaenge!=0)
{
Ersetzen (text, " ", " ");
Ersetzen (text, " \n", "\n");
vector<string> feld (1);
int n;
for (int i=0; i<text.length (); i++)
{
string &wort=feld [feld.size ()-1];
char &zeichen=text [i];
wort+=zeichen;
if (zeichen=='\n' || zeichen==' ' || zeichen=='-' || wort.length ()==zeilenlaenge)
feld.push_back ("");
}
text.erase ();
n=zeilenlaenge;
for (i=0; i<feld.size (); i++)
{
string &wort=feld [i];
char &letztesZeichen=wort [wort.length ()-1];
int laenge=wort.length ()-(letztesZeichen=='\n' || letztesZeichen==' '?1:0);
if (laenge<=n)
{
text+=wort;
n-=wort.length ();
if (letztesZeichen=='\n')
n=zeilenlaenge;
}
else
{
text+='\n';
n=zeilenlaenge;
i--;
}
}
Ersetzen (text, " \n", "\n");
}
}