Some time ago I was looking for a snippet to do a wordwrap for a certain size of line length without breaking up the words. It was working fair enough, but now when I started using it in edit control, I noticed it eats up multiple white space symbols in between. I am contemplating how to fix it or get rid of it completely if wstringstream is not suitable for the task. Maybe someone out there have a similar function?
void WordWrap2(const std::wstring& inputString, std::vector<std::wstring>& outputString, unsigned int lineLength)
{
std::wstringstream iss(inputString);
std::wstring line;
std::wstring word;
while(iss >> word)
{
if (line.length() + word.length() > lineLength)
{
outputString.push_back(line+_T("\r"));
line.clear();
}
if( !word.empty() ) {
if( line.empty() ) line += word; else line += +L" " + word;
}
}
if (!line.empty())
{
outputString.push_back(line+_T("\r"));
}
}
Wrap line delimiter symbol should remain \r
Instead of reading a word at a time, and adding words until you'd exceed the desired line length, I'd start from the point where you want to wrap, and work backwards until you find a white-space character, then add that entire chunk to the output.
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
void WordWrap2(const std::wstring& inputString,
std::vector<std::wstring>& outputString,
unsigned int lineLength) {
size_t last_pos = 0;
size_t pos;
for (pos=lineLength; pos < inputString.length(); pos += lineLength) {
while (pos > last_pos && !isspace((unsigned char)inputString[pos]))
--pos;
outputString.push_back(inputString.substr(last_pos, pos-last_pos));
last_pos = pos;
while (isspace((unsigned char)inputString[last_pos]))
++last_pos;
}
outputString.push_back(inputString.substr(last_pos));
}
As it stands, this will fail if it encounters a single word that's longer than the line length you've specified (in such a case, it probably should just break in the middle of the word, but it currently doesn't).
I've also written it to skip over whitespace between words when they happen at a line break. If you really don't want that, just eliminate the:
while (isspace((unsigned char)inputString[last_pos]))
++last_pos;