#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. Спасибо, Ричард! Я собираюсь изучить это подробнее и попытаться реализовать в своей программе. Я ценю, что вы нашли время ответить!