如何使用rfind()根据用户名分隔和打印字符串?

时间:2016-10-12 23:25:49

标签: c++ string

我不会在这里提出很多问题,所以我希望这个问题具体到可以回答。

我正在为我所在的软件构建课程开展一个项目,并且在部分任务中遇到了问题。基本上我们正在编写一个程序,允许创建新用户,然后这些用户可以发布消息。

每次发布​​消息时,都会附加到字符串(我正在调用message_buffer)。因此,即使多个用户发布,他们所有的消息都会被添加到此字符串中。用户名包含在"%("和")%"然后在那之后追加他们的信息。

现在,用户拥有的一个选项是打印他们的"墙页。"当他们选择打印他们的墙页时,只有该用户发布的消息将按相反的时间顺序打印。所以例如,如果message_buffer包含"%(简)%嘿$ ^你好吗?$ ^%(简)%你的夏天怎么样?$ ^" (" $ ^"字符串只表示用户输入了多行消息,后来被" \ n"转义序列替换)然后当用户选择打印出来时他们的墙页,它应该打印:

你的夏天过得怎么样?

你好吗?

为什么教授希望最新的消息在最顶层,我不知道,但是c' est la vie。

所以,我解决这个问题的方法是使用rfind()搜索"%("然后通过使用rfind()确定包含的名称以搜索")% &#34 ;.然后我将所附的名称与当前用户进行比较(因为只应发布他们的消息,并且message_buffer中可能有多个用户消息),如果它匹配当前用户的名称,我删除所有从"%("到最后,然后继续搜索。)如果名称​​ 匹配,那么我打印出所有内容,从&#34开始; %("直到结束(我有一个功能删除" $ ^"并用" \ n"替换它),并删除"% (名称)%"部分,因为用户名不应该包括在墙页中。)我继续搜索,直到我到达message_buffer的开头。

所以,如果只有一条消息,这可以正常工作,例如:"%(简)%嘿$ ^你的夏天怎么样?$ ^会正确打印出来。但是,如果message_buffer中有多个名称(就像我在开头给出的示例),那么它没有正确找到名称,因此无法正确打印出所有消息。

我认为这足以解释,所以这里是我创建的函数来尝试处理这个:

void parseMessages(string bufferIn)
{
    string message;
    string bCopy = bufferIn;
    string name;
    int index1;
    do  
    {
        index1 = bCopy.rfind("%(");
        name = bCopy.substr(index1 + 2, bCopy.rfind(")%") - 2);
        if (name != username)
        {
        bCopy.erase(index1, bCopy.length());
        }
        else if (name == username)
        {
            message = bCopy.substr(index1, bCopy.length());
            bCopy.erase(index1, bCopy.length());
        }
        message = format(message);
        cout << message << endl;
        if (index1 == 0)
        {
            index1 = -1;
        }
    } while (index1 >= 0);
}

所以,如果你要输入我给出的第一个例子,那里有两个&#34;%(简)%&#34;消息,由于某种原因,变量名称设置为&#34;简)%你的夏天怎么样?$ ^&#34;而我无法为我的生活找出原因。如果只有一个&#34;%(简)%&#34;字符串,然后它工作查找;变量名称设置为&#34; Jane&#34;并且消息打印出来。

我在这里做错了什么?任何帮助非常赞赏!

1 个答案:

答案 0 :(得分:0)

这应该提供一些见解。

#include <iostream>
#include <string>

template<class Func>
void reverse_iterate_messages(std::string const& buffer, Func&& f)
{
    auto current = buffer.size();

    while (current)
    {
        auto pos = buffer.rfind("%(", current - 1);
        auto end_name = buffer.find(")%", pos + 2);
        if (end_name < current)
        {
            auto name = buffer.substr(pos + 2, end_name - pos - 2);
            auto message = buffer.substr(end_name + 2, current - end_name - 2);
            f(name, message);
            current = pos;
        }
        else {
            break;   // incorrectly formatted string
        }
    }

}

void show(std::string const& name, std::string message)
{
    if (name == "Jane")
    {
        for (std::size_t pos = 0 ; pos < message.size() ; )
        {
            auto i = message.find("$^", pos);
            if (i == std::string::npos)
                break;
            message.replace(i, 2, "\n");
            pos = i + 1;
        }
        std::cout << message;
    }
}

int main()
{
    auto test_string = "%(Jane)%Hey$^How are you?$^%(Jane)%How was your summer?$^";
    reverse_iterate_messages(test_string, show);

}

预期产出:

How was your summer?
Hey
How are you?