2013-01-02 43 views
2

我做C++中的服务器应用程序,并且将其提供的HTML页面作为响应于HTTP请求。C++标准替代(S)的printf

的问题是,目前,我的网页被写在我的代码常量字符串,我字符串本身的写作过程中插入使用<<运营商和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结构混合的数据将在执行过程中发生改变。这意味着我不能简单地写整个页面在一个文件中,同时firstsecond,并third的字符串值,因为这些值会动态变化。

对于第一个请求我会发送页面first = "foo";,而在第二个请求我会有first = "anything else"

而且,我可以简单地从stdio.h回去sscanf/sprintf并插入我想要的文字 - 我只需要更换正确的格式(%s)字符串的差距,从文件中读取HTML结构,以及插入任何我想做的。

我想做到这一点在C++中,不C库函数,但我无法弄清楚用来做什么。什么是这种情况的C++标准解决

+1

你覆盖' \ n '部分。 – chris

+0

@chris感谢您指出,但它并没有真正影响到这里的问题。无论如何,我编辑过代码。 – Rubens

+0

@Rubens我不知道我的理解句子“偏偏虽然我不能简单的东西,在一个文件中的内容,因为与HTML结构混合的数据将在执行过程中发生改变。” - 请你澄清一下吗?你想达到什么目的? –

回答

4

标准C++没有直接等同于(s)printf样格式以外(s)printf本身。然而,有很多提供此功能,如cppformat库,包括C++实现的Python的str.format和安全printf的格式库。

也就是说,我建议使用模板引擎,请参阅 C++ HTML template framework, templatizing library, HTML generator library

或者,你可以随时推倒重来,并通过读取文件,并替换参数占位符的一些编写自己的模板引擎。

+1

http://en.cppreference.com/w/cpp/io/c/fprintf - 从技术上讲,标准C++确实包含诸如'sprintf'之类的东西。不过,使用模板框架是一个很好的建议。 –

+0

@NateKohl但它是在'stdio.h'还是'iostream'? – Rubens

+0

它在(也),不。但它仍然是C++的一部分。 –

2

什么:

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); 
+0

我想OP希望从文件中读取HTML模板,然后替换参数。 – vitaut

+0

这就是我目前正在做的事情;我想摆脱这种* HTML编码*在C++中,几乎使用*占位符*,但我想有一些标准的C++方法该工厂 - 像C标准'(S)printf'。 – Rubens

2

你可以得到这样的期望的结果:

  1. 存储静态HTML的文件中,占位符的动态文本
  2. 阅读HTML文件转换成std::string
  3. 对于每个片动态文本的,找到其字符串(std::string::find)在占位符和与所述动态文本(std::string::replace)替换占位符。
  4. 写入修改后的字符串到最终目的地。
+0

这正是我一直计划要做的;我只是想知道,如果我可以用'(s)printf'替换'%s'的简单,但是,正如@vitaut所说,似乎没有*直接等价的*。 – Rubens

+0

@Rubens:如果你愿意,你仍然可以使用printf。 – vitaut

+0

@vitaut是的,我知道,以及我可以使用'printf'作为'std :: cout'的一些工作;我只是想知道是否有更多的C++ *标准化*来实现这一点。看来我得坚持'sprintf',反正\ = – Rubens

1

如果你不想使用框架其他答案(正确地)建议,我想你可以从这个小程序的灵感:

#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; 
} 
+0

安迪,我真的很感谢你的迅速,但这是一个“Bart van Ingen Schenau”建议的实施;我的意志是真的知道是否有隐藏的C++的一些宝贵的功能,可能在'iostream'中,它可以完成和'(s)printf'完全相同的功能。 +1耐心和及时。对不起,如果我一开始就不够清楚。 – Rubens

+0

没问题,我们都在这里学习,有时候提出正确的问题比给出正确答案困难。欢呼 –

+1

顺便说一句,Boost.Format可能就像你正在寻找的东西。它不如'printf'高效,但它做同样的事情并确保类型安全。 –