tags:

views:

144

answers:

5

If i have a string as such

"I am not here... \n..Hello\n.\n....Whats happening"

I want to replace the above string so:

"I am not here... \n..Hello\n. \n....Whats happening"
                              ^ Space added

Just a bit of a background on what im doing. Im using sendmail in C++ and \n.\n is End Of Message Equivalent of sendmail. I just created a class that uses sendmail to send mails. but obviously if the user from the outsite gives sendmail that command i want it to be removed. Here is my message function just incase.:

//Operator to add to the message
void operator<<(string imessage){
    if (imessage != ""){ message += imessage; } 
}

How would i go about doing this. Thanks in advance :D

+1  A: 

Boost has Boost.Regex (a regular expression module). Might be overkill if this is the only replacement you need to do.

ezod
Yes a bit overkill, but i was wondering for later what regex functionality does C++ have. Plus 1 for solving that :D
Shahmir Javaid
i need that for nl2br function for C :D
Shahmir Javaid
+2  A: 

Look up String.find and String.replace

For example (not tested)

string endOfMessage = "\n.\n";
string replacement = "\n. \n";
size_t position;

while (position = message.find(endOfMessage))
{
   message.replace(position, endOfMessage.length(), replacement);
}
Dan McGrath
This will A. perform horribly and B. break if the source and replacement are the same, or any part of the replacement is the source. See my answer for a corrected version....
Billy ONeal
Oh, and find returns npos rather than 0 on failure.
Billy ONeal
That is indeed true.
Dan McGrath
+1  A: 

Use std::search and the insert method of sequence containers such as string, deque, or whatever you use to store the message text.

typedef std::string::iterator SIter; // or whatever container you use
static const char *end_seq = "\n.\n";
for ( SIter tricky_begin = msg.begin();
  tricky_begin = std::search( tricky_begin, msg.end(), end_seq, end_seq+3 ),
  tricky_begin != msg.end(); ) {
    tricky_begin = msg.insert( tricky_begin + 2, ' ' );
}
Potatoswatter
As for the newline-at-beginning issue, you should initialize the message with a leading newline and keep it there. Sounds like a broad semantic issue of the SMTP format.
Potatoswatter
+3  A: 

This is my last version :)
This code handles the case mentioned by @Greg Hewgill

string& format_text(string& str)
{
    const string::size_type dot_offset = 2;
    string::size_type found_at_start = str.find("\n.\n"),
                    found_at = str.find("\n.\n");

    if(found_at_start != string::npos)
        str.insert(0, " ");

    while(found_at != string::npos)
    {
        str.insert(found_at+dot_offset+1, " ");
        found_at = str.find("\n.\n", found_at+1);
    }
    return str;
}

int main()
{
    string text = ".\nn\n.\nn";
    std::cout << format_text(text);
}
AraK
Thanks worked.. :D
Shahmir Javaid
+2  A: 

This is derived from Dan McG's answer so upvote him ;)

string endOfMessage = "\n.\n";
string replacement = "\n. \n";
size_t position;

while (position = message.find(endOfMessage, position) != message.npos)
{
   message.replace(position, endOfMessage.length(), replacement);
   position += replacement.length();
}
Billy ONeal