【网通】点击此处下载源程序及EXE文件 【电信、网通】点击此处下载源程序与EXE文件
【下载说明】
1、单击上面这个地址,打开下载页面。
2、点普通下载--等待30秒--点“下载”按钮--保存
点击此处查看原文
Cpphtml 是将你的C++代码转换为HTML页面的类库.如果你有一个C++文件, 比如是myprogram.cpp, 然后你想将它放到自己的网站上, 那么你就可以使用Cpphtml来完成这个工作,Cpphtml会将其转换为HTML并附带所有的注释、关键字和预处理的高亮显示。Cpphtml将会将所有的输出指向cout,因此如果你想要创建一个HTML文件的话,你可以重定向至一个文件就可以了。
C:\>cpphtml myprogram.cpp >myprogram.htm
Cpphtml会将所有的Tab键变成4个空格。如果你想要Tab的大小是8个空格的话,你可以在命令行上指定Tab的大小。
C:\>cpphtml myprogram.cpp 8 >myprogram.htm
HTML代码包含一个<style>元素,它会包含注释、关键字和预处理器的风格。因此,如果你想要改变关键字的颜色的话,没有必要使用搜索-替换的操作。比如,如果你想要所有的关键字是粗体,只需要改变.keyword风格就可以了,如下:
.keyword{color:rgb(0,0,255);font-weight:bold}
很简单。
我测试过DinkumwareSTL文件、Cpphtml的源文件和一个较大的Microsoft CPP文件。结果很不错。Cpphtml使用Borland c++ 5.5命令行来编译的:bcc32 cpphtml.cpp
#include<fstream>
#include<string>
#include<ctype.h>
如果没有指定Tab大小的话,Cpphtml默认是用4个空格替换所有的Tab键的。如果你想要默认的Tab大小是8个空格的话,改变_TABSIZE宏为8即可。
#define _TABSIZE 4
using namespace std;
int tabsize = _TABSIZE;
Token是一个代表代码块的类。一个Token会有注释、预处理命令、关键字和代码。不包含注释、预处理命令和关键字的部分都叫做代码。注意他们不是设置或获取方法:因为operator>>
和operator<<
是Token类的友类,这些我们都不需要.
class token {
public:
token() : _what(code) {}
protected:
enum type {code, comment, pp, keyword};
string _str;
type _what;
friend istream& operator>>(istream&, token&);
friend ostream& operator<<(ostream&, const token&);
};
函数iskeyword()
返回true
如果字符串 s
是一个C++关键字的话, 如果不是,返回false
。可能你不认识其中的一些关键字,比如and。那些不需要所有ASCII字符的编程者可能会用到。但是,我还没见过有这样关键字的代码。
bool iskeyword(const string& s)
{
static const char* keywords[] = {
"and",
"and_eq",
"asm",
"auto",
"bitand",
"bitor",
"bool",
"break",
"case",
"catch",
"char",
"class",
"compl",
"const",
"const_cast",
"continue",
"default",
"delete",
"do",
"double",
"dynamic_cast",
"else",
"enum",
"explicit",
"export",
"extern",
"false",
"float",
"for",
"friend",
"goto",
"if",
"inline",
"int",
"long",
"mutable",
"namespace",
"new",
"not",
"not_eq",
"operator",
"or",
"or_eq",
"private",
"protected",
"public",
"register",
"reinterpret_cast",
"return",
"short",
"signed",
"sizeof",
"static",
"static_cast",
"struct",
"switch",
"template",
"this",
"throw",
"true",
"try",
"typedef",
"typeid",
"typename",
"union",
"unsigned",
"using",
"virtual",
"void",
"volatile",
"wchar_t",
"while",
"xor",
"xor_eq"
};
for (int i = 0; i < sizeof(keywords) / sizeof(char*); i++)
if (string(keywords[i]) == s)
return true;
return false;
}
函数containspp()
返回true
如果字符串 s
包含预处理命令.一个Token类型pp 可以包含一个形如 "#...define
"的预处理命令,因此, 我们必须找到它的子字符串。.
bool containspp(const string& s)
{
static const char* pptokens[] = {
"define",
"elif",
"else",
"endif",
"error",
"if",
"ifdef",
"ifndef",
"include",
"line",
"pragma",
"undef"
};
for (int i = 0; i < sizeof(pptokens) / sizeof(char*); i++)
if (s.find(pptokens[i]) != string::npos)
return true;
return false;
}
Operator>>
从输入流中获取Token.它识别 "//
"和 "/*...*/
"注释, 形如"#...define
"的预处理命令,和关键字.为了避免字符串中的关键字被高亮,也识别常量字符串。
istream& operator>>(istream& is, token& t)
{
t._str = "", t._what = token::code;
int c = is.get();
switch (c) {
case '/':
c = is.get();
if (c == '*') {
t._str = "/*";
t._what = token::comment;
while (1) {
c = is.get();
if (c == EOF)
return is.unget(), is.clear(), is;
if (c == '/') {
if (t._str.length() > 2 &&
t._str[t._str.length() - 1] == '*') {
return t._str += '/', is;
}
}
t._str += (char)c;
}
} else if (c == '/') {
t._str = "//";
t._what = token::comment;
c = is.get();
while (c != '\n' && c != EOF) {
t._str += (char)c;
c = is.get();
}
if (c == '\n') {
t._str += '\n';
}
return is;
}
t._str = '/';
return is.unget(), is.clear(), is;
case '#':
t._str = '#';
c = is.get();
while (strchr(" \r\n\t", c)) {
t._str += (char)c;
c = is.get();
}
if (c == EOF)
return is.unget(), is.clear(), is;
while (strchr("abcdefghijklmnopqrstuvwxyz", c)) {
t._str += (char)c;
c = is.get();
}
is.unget(), is.clear();
if (containspp(t._str))
t._what = token::pp;
return is;
case '\'':
case '"': {
char q = (char)c;
t._str = q;
while (1) {
c = is.get();
if (c == EOF)
return is.unget(), is.clear(), is;
if (c == q) {
if (t._str.length() >= 2) {
if (!(t._str[t._str.length() - 1] == '\\' &&
t._str[t._str.length() - 2] != '\\'))
return t._str += q, is;
} else {
return t._str += q, is;
}
}
t._str += (char)c;
}
}
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'i':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
t._str += (char)c;
c = is.get();
while (isalpha(c) || isdigit(c) || c == '_') {
t._str += (char)c;
c = is.get();
}
is.unget(), is.clear();
if (iskeyword(t._str))
t._what = token::keyword;
return is;
case EOF:
return is;
default:
t._str += (char)c;
c = is.get();
while (c != '/' && c != '#' && !strchr("abcdefgilmnoprstuvwx", c) &&
c != '\'' && c != '"' && c != EOF) {
t._str += (char)c;
c = is.get();
}
is.unget(), is.clear();
return is;
}
}
函数html()
替换字符串s里的字符 '&
', '<
', '>
'和 '"
',使用它们在HTML里面同等的字符,并且使用空格来替换Tab。
string html(const string& s)
{
string s1;
string::size_type i;
for (i = 0; i < s.length(); i++) {
switch (s[i]) {
case '&':
s1 += "&";
break;
case '<':
s1 += "<";
break;
case '>':
s1 += ">";
break;
case '"':
s1 += """;
break;
case '\t':
s1.append(tabsize, ' ');
break;
default:
s1 += s[i];
}
}
return s1;
}
Operator<<
将一个Token输出至输出流.代码也很直接.
Collapse | Copy Code
ostream& operator<<(ostream& os, const token& t)
{
if (t._what == token::code)
cout << html(t._str);
else if (t._what == token::comment)
cout << "<span class=comment>" << html(t._str) << "</span>";
else if (t._what == token::keyword)
cout << "<span class=keyword>" << html(t._str) << "</span>";
else if (t._what == token::pp)
cout << "<span class=pp>" << html(t._str) << "</span>";
else
cout << html(t._str);
return os;
}
这是Cpphtml的进入点。所有的代码将会被包装在<pre>元素里面。通过重载operator>>
和operator<<
,while
会很简短.所有的输出都被送到cout
里
.
int main(int argc, char **argv)
{
if (argc != 2 && argc != 3) {
cout << "usage: cpphtml file [tab size]" << endl;
return 0;
}
ifstream is(argv[1]);
if (!is.good()) {
cerr << "bad input file" << endl;
return -1;
}
if (argc == 3) {
tabsize = atoi(argv[2]);
if (tabsize <= 0)
tabsize = _TABSIZE;
}
cout << "<html>" << endl
<< "<head>" << endl
<< "<style>" << endl;
cout << ".keyword{color:rgb(0,0,255);}" << endl;
cout << ".comment{color:rgb(0,128,0);}" << endl;
cout << ".pp{color:rgb(0,0,255);}" << endl;
cout << "</style>" << endl << "<body>" << endl;
cout << "<pre style=\"font-family:courier;font-size:10pt\">";
token t;
while (is >> t) {
cout << t;
}
cout << "</pre>" << "</body>"
<< endl << "</html>" << endl;
return 0;
}
【更多阅读】