#include <iostream>
#include <string>
#include <pcrecpp.h>
using namespace std;
using namespace pcrecpp;
string wordwrap(string s, int col) {
char width[10];
string str(s);
RE("\\n").GlobalReplace(" ", &str);
RE(" ").GlobalReplace(" ", &str);
sprintf(width,"%d",col);
RE("\\S{" + string(width) + "})(?=\\S)").GlobalReplace("\\1", &str);
RE("(.{1," + string(width) + "})(?:\\s+|$)").GlobalReplace("\\1\n", &str);
return str;
}
int main(int argc, char** argv) {
string test("These are the times that\n try men's souls");
cout << test << endl;
cout << wordwrap(test,10) << endl;
cout << wordwrap(test,20) << endl;
}
char *wrap (char *input, int length)
{
static char wrapped_buf[MAX_STRING_LENGTH];
char *pti, *pto, *last_i_space, *last_o_space;
int cnt = 0;
last_o_space = pto = wrapped_buf;
last_i_space = pti = input;
while (TRUE)
{
*pto = *pti;
switch (*pto)
{
case '\0':
return wrapped_buf;
break;
case ' ':
last_o_space = pto;
last_i_space = pti;
break;
case '\n':
case '\r':
cnt = 0;
pto++;
pti++;
continue;
}
pto++;
pti++;
cnt++;
if (cnt >= length)
{
if (*pti == '\n' || *pti == '\0')
{
continue;
}
if (*pti == ' ')
{
last_o_space = pto;
last_i_space = pti;
}
if (pto - last_o_space > 20)
{
*pto = '\r';
pto++;
*pto = '\n';
pto++;
cnt = 0;
}
else
{
pto = last_o_space;
*pto = '\r';
pto++;
*pto = '\n';
pto++;
pti = last_i_space;
pti++;
cnt = 0;
}
}
}
return wrapped_buf;
}
___ ——————————————– ___
/ \_______ /| |\ _______/ \
| | | This is a sample of text that is | | | |
| _______| | far too long to fit on this scroll | |_______| |
\___/ \| |/ \___/
——————————————–
send_to_char(" ___ ——————————————– ___",ch);
send_to_char" / \_______ /| |\ _______/ \",ch);
sprintf(buf,"| | | %s | | | |",wordwrap(1,35,text));
send_to_char(buf,ch);
sprintf(buf,"| _______| | %s | |_______| |"wordwrap(2,35,text));
send_to_char(buf,ch);
send_to_char(" \___/ \| |/ \___/",ch);
send_to_char(" ——————————————– ",ch);
RE("\\n").GlobalReplace(" ", &str); // Replace all linefeeds with spaces
RE(" ").GlobalReplace(" ", &str); // Replace all double spaces with single spaces
sprintf(width,"%d",col); // copy column width to string
// Go through string breaking it into fixed size chunks column 'width' or less,
// ensuring that each chunk begins with a non whitespace characters and doesn't
// end on one. (don't break words up)
RE("\\S{" + string(width) + "})(?=\\S)").GlobalReplace("\\1", &str);
// Append linefeeds to end of column 'width' chunks.
RE("(.{1," + string(width) + "})(?:\\s+|$)").GlobalReplace("\\1\n", &str);
char *wordwrap( int lines, int length, const char *argument )
{
static char strwrap[50][MAX_STRING_LENGTH];
int i,b,n,r,count, word;
count = n = b = 0;
for ( i = 0; i < strlen(argument); i++ )
{
count++;
word = 0;
if(argument[i] == ' ')
for(r = i+1;argument[r] != ' ';r++)
word++;
if(count+word > length && argument[i] == ' ')
{
strwrap[n][b] = '\0';
count = b = 0;
n++;
}
else
{
strwrap[n][b] = argument[i];
b++;
}
}
if(lines > n)
{
n++;
for(i = 0;i < length;i++)
strwrap[n][i] = ' ';
strwrap[n][i+1] = '\0';
return strwrap[n];
}
else return strwrap[lines];
}
My intention is to design a function that divides a string into an array and returns only the line
requested in the function call. This way you can put it in a loop to display the whole wordwrapped
string, or you can do what I'm trying to do, design an ASCII art menu and put a string in several
lines of ASCII art without screwing with the alignment of things.
Everything works but with one problem… I counts the length of the string AFTER adding each word.
I added in a "read-ahead" loop to prevent that but for some reason its not working. I must be blind
or something because I can NOT see what is wrong here.
Please note that I'm extremely rusty in C so my function is a mess… please don't mock my lack of skills.
PS: Since this actually does work 100% (just not the way I want it to), feel free to use it if you want.
Just drop me a line and let me know that you do :)