Question

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

Était-ce utile?

La solution

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;

Autres conseils

If you don't want to loose space characters, you need to add the following line before doing any reads:

iss >> std::noskipws;

But then using >> with a string as a second argument won't work well w.r.t. spaces.

You'll have to resort to reading chars, and manage them in an ad'hoc manner yourself.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top