boost::format - attempting to use HTML as formatter string - need some help
I'm attempting to use boost::format, where my formatting string is the HTML below. I intend to insert 3x std::strings at locations specified by %s placeholders.
开发者_如何学PythonIn other words - I'm opening the below *.html file for reading, read it's contents into a single std::string and use it as the formatter. Next I'm attempting to do the following :
std::string output = (boost::format(formatter) % str1 % str2 % str3).str();
Where str1-3 are strings containing text which I'm attempting to insert - obviously. The format attempt throws an exception saying that the format string is ill-formed. I've been trying to analyze it for the better part of the last 2 hrs but I've failed and I need some help.
What is wrong with the below HTML - why can't it become the proper formatter string? What are the limitations I should be aware of ?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>KP&D</title>
<style type="text/css">
html, body
{
height: 100%;
margin: 0;
padding: 0;
}
img#bg
{
position:fixed;
top:0;
left:0;
width:100%;
height:100%;
}
#content
{
position:relative;
z-index:1;
}
</style>
</head>
<body>
<img src="Images/PageBackground.png" alt="background image" id="bg" />
<div id="content">
<br/>
<img src="Images/MyLogoReflected.png" alt="logo image"/>
<br />
<img src="Images/PDC_StatusPage.png" alt="remote status page image" />
<br />
<img src="Images/PDC_RemoteConfiguration.png" alt="remote config image" />
<br />
%s
<br />
<img src="Images/PDC_RemoteSubsystemStatus.png" alt="remote status image" />
<br />
%s
<br />
<img src="Images/PDC_RemoteConnectivityStatus.png" alt="remote status image" />
<br />
%s
<br />
</div>
</body>
</html>
Here's the code snippet responsible for loading the forementioned file :
#include <string>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
int main()
{
std::ifstream ifs("welcome.html"); // the html is in that file
if(!ifs.good())
return 1;
std::string buffer = "";
while(!ifs.eof())
{
char buf[256];
ifs.getline(buf, 256);
buffer += buf;
}
buffer = boost::trim_right_copy(buffer);
const std::string str1 = "aaa";
const std::string str2 = "bbb";
const std::string str3 = "ccc";
std::string Out = "";
try{
Out = (boost::format(buffer)
% str1
% str2
% str3
).str();
} catch(std::exception &e)
{
err = e.what();
return 1;
}
return 0;
}
boost::format
uses %
to delimit format specifications; so the %
characters in your CSS are confusing it; it is trying to evaluate them as format specifications. You'll need to replace those with %%
to get just a literal %
character in the output.
If that doesn't help, then I would recommend trying to edit your template down into smaller pieces, until you find a piece as small as possible that demonstrates the problem. Once you do that, you may discover the problem yourself, but if not, edit your post to include that smaller snippet that still demonstrates the problem (preferably 1 or 2 lines of less than 80 characters each), as well as the exact error that you are getting from Boost. Likewise, it would help if you posted a snippet of the code you are using to read in the file, and invoke boost::format
; a complete program with just a few lines of code for reading the template in, and printing the output of boost::format
, would allow us to see if there's anything in your code that might be causing problems (and again, that may help you isolate the problem yourself).
The code you posted (edited a bit so it actually works; you left out declarations of buffer
and err
), works just fine with the template you posted, if all of the %
signs in the CSS are replaced by %%
, as I originally suggested. Here's the edited code (including output to check that it works):
#include <string>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <iostream>
int main()
{
std::ifstream ifs("template.html"); // the html is in that file
std::string buffer, err;
if(!ifs.good())
return 1;
while(!ifs.eof())
{
char buf[256];
ifs.getline(buf, 256);
buffer += buf;
}
buffer = boost::trim_right_copy(buffer);
const std::string str1 = "aaa";
const std::string str2 = "bbb";
const std::string str3 = "ccc";
std::string Out = "";
try{
Out = (boost::format(buffer)
% str1
% str2
% str3
).str();
} catch(std::exception &e)
{
err = e.what();
std::cout << err << std::endl;
return 1;
}
std::cout << Out;
return 0;
}
And here's the edited template:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>KP&D</title>
<style type="text/css">
html, body
{
height: 100%%;
margin: 0;
padding: 0;
}
img#bg
{
position:fixed;
top:0;
left:0;
width:100%%;
height:100%%;
}
#content
{
position:relative;
z-index:1;
}
</style>
</head>
<body>
<img src="Images/PageBackground.png" alt="background image" id="bg" />
<div id="content">
<br/>
<img src="Images/MyLogoReflected.png" alt="logo image"/>
<br />
<img src="Images/PDC_StatusPage.png" alt="remote status page image" />
<br />
<img src="Images/PDC_RemoteConfiguration.png" alt="remote config image" />
<br />
%s
<br />
<img src="Images/PDC_RemoteSubsystemStatus.png" alt="remote status image" />
<br />
%s
<br />
<img src="Images/PDC_RemoteConnectivityStatus.png" alt="remote status image" />
<br />
%s
<br />
</div>
</body>
</html>
I've managed to locate the issue.
after optimizing the file reading & fixing the % characters it worked fine. Thank you all very very much.
Here's a cool snippet I've found on how to read whole file to string at once :)
buffer = std::string((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
精彩评论