Я делаю серверное приложение на C ++, и оно предоставляет HTML-страницу в ответ на HTTP-запросы.
Проблема в том, что в настоящее время моя веб-страница написана как постоянная строка в моем коде, и я вставляю другие строки, используя <<
оператор и std::stringstream
еще во время написания самой строки. Смотрите пример, чтобы прояснить ситуацию:
std::string first("foo");
std::string second("bar");
std::string third("foobar");
std::stringstream ss;
ss << "<html>\n""<head>\n""<title>Bitches Brew</title>\n""</head>\n""<body>\n""First string: "<< first << "\n""Second string: "<< second << "\n""Third string: "<< third << "\n""</body>\n""</html>";
Бывает, хотя я не могу просто вставить содержимое в файл, потому что данные, смешанные со структурой HTML, изменятся во время выполнения. Это означает, что я не могу просто записать всю страницу в файл со строковыми значениями first
, second
, а также third
потому что эти значения будут меняться динамически.
Для первого запроса я отправлю страницу с first = "foo";
тогда как во втором запросе я бы first = "anything else"
,
Кроме того, я мог бы просто вернуться к sscanf/sprintf
от stdio.h
и вставьте текст, который я хочу — мне просто нужно заменить пропуски строк в правильном формате (%s
), прочитайте структуру HTML из файла и вставьте все, что я хотел.
Я хотел бы сделать это в C ++, без функций библиотеки C, но я не мог понять, что использовать для этого. Что бы C ++ стандарт решение для этого?
Стандарт C ++ не имеет прямого эквивалента (s)printf
как форматирование, кроме (s)printf
сам. Тем не менее, есть много библиотек форматирования, которые предоставляют эту функциональность, например cppformat библиотека, которая включает в себя реализацию Python на C ++ str.format
и безопасно printf
,
Тем не менее, я бы рекомендовал вместо этого использовать шаблонизатор
Фреймворк HTML C ++, библиотека шаблонов, библиотека генератора HTML .
Или вы всегда можете заново изобрести колесо и написать свой собственный шаблонизатор, читая файл и заменяя некоторые заполнители аргументами.
Как насчет:
void RenderWebPage(std::stringstream& ss, std::string& first, std::string& second, std::string& third)
{
ss << "<html>\n""<head>\n""<title>Bitches Brew</title>\n""</head>\n""<body>\n""First string: "<< first << "\n""Second string: "<< second << "\n""Third string: "<< third << "\n""</body>\n""</html>";
}
И вы можете назвать это так:
std::stringstream ss;
std::string first("foo");
std::string second("bar");
std::string third("foobar");
RenderWebPage(ss, first, second, third);
first = "anything else";
RenderWebPage(ss, first, second, third);
second = "seconds too";
RenderWebPage(ss, first, second, third);
Вы можете получить желаемый результат следующим образом:
std::string
std::string::find
) и замените заполнитель на динамический текст (std::string::replace
).Если вы не хотите использовать фреймворк, как подсказывают другие ответы (правильно), я думаю, вы можете черпать вдохновение из этой маленькой программы:
#include <iostream>
#include <map>
using namespace std;
string instantiate_html(string const& templateHTML, map<string, string> const& replacements)
{
string outputHTML = templateHTML;
for (auto& entry : replacements)
{
string placeholder = "<$" + entry.first + "$>";
size_t it = outputHTML.find(placeholder);
if (it != string::npos)
{
outputHTML.replace(it, placeholder.size(), entry.second);
}
}
return outputHTML;
}
int main()
{
map<string, string> replacements;
replacements["name"] = "Mark";
replacements["surname"] = "Brown";
// Normally you would read this string from your template file
string templateHTML = "<html><body><$name$><$surname$></body></html>";
string outputHTML = instantiate_html(templateHTML, replacements);
cout << outputHTML;
return 0;
}