Is there a common C/C++ library (or common technique) for taking a line(s) of input text and splitting the words into separate lines. Where each line of output has a max width and words are not split across lines. Whitespace being collapsed or preserved is ok. Punctuation must be preserved. Small and compact library is preferred.
I could easily spend an afternoon putting something together that works, but would like to know if there is something common out there so I don't re-invent the wheel. Bonus points if the input line can contain a format specifier to indicate an indention level for the output lines.
Example input: "Shankle drumstick corned beef, chuck turkey chicken pork chop venison beef strip steak cow sausage. Tail short loin shoulder ball tip, jowl drumstick rump. Tail tongue ball tip meatloaf, bresaola short loin tri-tip fatback pork loin sirloin shank flank biltong. Venison short loin andouille.
Example output (target width = 60)
123456789012345678901234567890123456789012345678901234567890 Line added to show where 60 is
Shankle drumstick corned beef, chuck turkey chicken pork
chop venison beef strip steak cow sausage. Tail short loin
shoulder ball tip, jowl drumstick rump. Tail tongue ball tip
meatloaf, bresaola short loin tri-tip fatback pork loin
sirloin shank flank biltong. Venison short loin andouille.
Here's my approach, it's certainly not the fastest but I tried to make it as readable as possible. The result is the same as your example.
#include <iostream>
#include <string>
std::string splitInLines(std::string source, std::size_t width, std::string whitespace = " \t\r")
{
std::size_t currIndex = width - 1;
std::size_t sizeToElim;
while ( currIndex < source.length() )
{
currIndex = source.find_last_of(whitespace,currIndex + 1);
if (currIndex == std::string::npos)
break;
currIndex = source.find_last_not_of(whitespace,currIndex);
if (currIndex == std::string::npos)
break;
sizeToElim = source.find_first_not_of(whitespace,currIndex + 1) - currIndex - 1;
source.replace( currIndex + 1, sizeToElim , "\n");
currIndex += (width + 1); //due to the recently inserted "\n"
}
return source;
}
int main() {
std::string source = "Shankle drumstick corned beef, chuck turkey chicken pork chop venison beef strip steak cow sausage. Tail short loin shoulder ball tip, jowl drumstick rump. Tail tongue ball tip meatloaf, bresaola short loin tri-tip fatback pork loin sirloin shank flank biltong. Venison short loin andouille.";
std::string result = splitInLines(source , 60);
std::cout << result;
return 0;
}