Как использовать rfind() для разделения и печати строки в соответствии с именем пользователя?

#c #string

#c #строка

Вопрос:

Я не задаю здесь много вопросов, поэтому надеюсь, что это достаточно конкретно, чтобы на него можно было ответить.

Я работаю над проектом для класса разработки программного обеспечения, в котором я участвую, и у меня возникли проблемы с частью задания. По сути, мы пишем программу, которая позволяет создавать новых пользователей, а затем эти пользователи могут отправлять сообщения.

Каждый раз, когда публикуется сообщение, оно добавляется к строке (которую я называю message_buffer ). Итак, даже если публикуют несколько пользователей, все их сообщения просто добавляются в эту строку. Имена пользователей заключаются в «% (» и «)%», а затем после этого добавляется их сообщение.

Теперь один из вариантов, который есть у пользователя (пользователей), — это распечатать свою «страницу на стене». Когда они решают распечатать свою страницу на стене, только сообщения, отправленные этим пользователем, должны печататься в обратном хронологическом порядке. Так, например, если message_buffer содержит «%(Jane)% Hey $ ^Как дела? $ ^% (Jane)%Как прошло твое лето? $ ^» (строка «$ ^» просто указывает, что пользователь вводит многострочное сообщение, а позже заменяется на escape-последовательность » n») затем, когда пользователь выбирает распечатать свою стенустраница, она должна печатать:

Как прошло ваше лето?

Привет

Как дела?

Я не знаю, почему профессор хочет, чтобы самые последние сообщения были вверху, но это так.

Итак, мой подход к этой проблеме заключался в использовании rfind() для поиска «%(«, а затем для определения вложенного имени с помощью rfind() для поиска «)%». Затем я сравниваю имя, приложенное к текущему пользователю (поскольку должны публиковаться только их сообщения, а в message_buffer может быть несколько пользовательских сообщений), и если оно не соответствует имени текущего пользователя, я стираю все, начиная с «%(» до конца, а затем продолжаю поиск. Если имя действительно совпадает, то я распечатываю все, начиная с «%(» до конца (у меня есть функция, которая удалила «$ ^» и заменила его на » n», а также удаляет часть «% (name)%», поскольку имя пользователя нене должно быть включено в страницу стены). Я продолжаю поиск, пока не дойду до начала message_buffer .

Итак, это отлично работает, если есть только одно сообщение, например: «% (Jane)% Привет $ ^Как прошло ваше лето? $ ^ будет распечатан правильно. Но, если в 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);
}
  

Итак, если вы должны были ввести первый пример, который я привел, где есть два сообщения «% (Jane)%», по какой-то причине для имени переменной установлено значение «Jane)% Как прошло твое лето? $ ^», и я ни за что на свете не могу понять, почему. Если есть только одна строка «% (Jane)%», то она работает find; Имя переменной устанавливается на «Jane», и сообщение выводится нормально.

Что я здесь делаю не так? Любая помощь приветствуется!

Комментарии:

1. обязательно ли использовать rfind? допустимо ли извлекать все сообщения в вектор, а затем просто инвертировать вектор?

2. нет, нельзя использовать вектор для хранения сообщений, это должна быть строка (отстой, я знаю). И я использую только rfind(), поэтому сначала распечатываю самые последние сообщения. Не мог придумать другого способа сделать это…

Ответ №1:

Это должно дать некоторое представление.

 #include <iostream>
#include <string>

template<class Func>
void reverse_iterate_messages(std::string constamp; buffer, Funcamp;amp; 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 constamp; 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?
  

Комментарии:

1. Спасибо, Ричард! Я собираюсь изучить это подробнее и попытаться реализовать в своей программе. Я ценю, что вы нашли время ответить!