Thread: Searching for and replacing newlines in strings.

  1. #1
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147

    Searching for and replacing newlines in strings.

    This is sort of a complicated question so I'll keep it as brief and simple as I can.

    I found a function that tokenizes a string based on spaces. This works fine.

    However, the string containes newlines and so any token that has a newline after it is stored as the token with the newline.

    I built a second loop after the first tokenizing loop that iterates through the vector, finds a string with a newline and inserts a blank string. I've fiddled with the position of the increment/decrement operators with no success -- the 'blank' string is indeed inserted but never in the correct position (either before the string containing the newline or after the following string). Part of this stems from having avoided string manipulations like the plague so now I'm stuck. Obviously what I wrote is not what I need and isn't correct.

    Code:
    vector<string> mTokens;
    
    // Skip leading spaces and find position of the first word.
    Uint lastPosition = text.find_first_not_of(" ", 0);
    Uint curPosition = text.find_first_of(" ", lastPosition);
    
    // Iterate over string and add individual words to a list of words.
    while(curPosition != string::npos || lastPosition != string::npos)
    {
    	mTokens.push_back(text.substr(lastPosition, curPosition - lastPosition));
    	lastPosition = text.find_first_not_of(" ", curPosition);
    	curPosition = text.find_first_of(" ", lastPosition);
    }
    
    vector<string>::iterator i = mTokens.begin();
    
    // Iterate through all words to find newline characters and add a blank line where newlines are found.
    while(i != mTokens.end())
    {
    	if(i->find("\n") != string::npos)
    		i = mTokens.insert(++i, "");
    
    	i++;
    }
    Secondly, there may be cases where there are several newlines. How can I properly account for that? I figured that, assuming a particular string has more than one newline after it, that I could simply truncate that newline off the string but this has the effect of truncating characters off the string, not stripping the newline.

    Thanks for your time.

  2. #2
    Registered User
    Join Date
    Sep 2009
    Posts
    63
    I think you might want to take a look at the stringstream class, as with that, these operations should be fairly easy. You can use its getline function to read until you encounter your specified delimiter. In your case, you could read until you get to the newline character. You can then append a space. But before you do that, you could check to be sure the string in question actually has data in it.

    Here's a quick example:

    Code:
    #include <sstream>
    #include <string>
    #include <iostream>
    
    int main()
    {
         std::string inString = "abcdefg\nhijklmno\n";
         std::string outString = "";
         std::stringstream stringHandler(inString);
         
         std::getline(stringHandler, outString, '\n'); 
         std::cout << outString << std::endl; //write out abcdefg
    
         std::getline(stringHandler, outString, '\n');
         std::cout << outString << std::endl; //write out nhijklmno
         return 0;
    }

  3. #3
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147
    I wasn't actually intending to replace the newline with a space -- the purpose for this function was to build the token list with empty strings indicating a newline. Each word would then be, one after the other, appended to a string until a miximum length was reached. That string would be pushed into a 'formatted strings' vector and the process would be repeated until all tokens were used. This was used for 'wrapping' text within a constrained area.

    However, I think that using stringstreams will be helpful in achieving this with my current line of thinking. I'm just not sure that my current line of thinking is actually a good method as I'm convinced there's a better method. I'll do a bit of googling to see what other methods may be avialable.

    Thanks for your help!

Popular pages Recent additions subscribe to a feed