2012年(158)
分类: C/C++
2012-11-20 11:13:09
Tree包含名称,和子Tree列表,在流中形式形如:
a
b
c
d
e
f
注1: html中无法显示Tab符号,所以我以8个空格代替
注2:
不同的编译器应当使用不同的文本格式,比如VC++使用windows文本格式(\r\n作为行间隔),dev-cpp使用Unix文本格式(\n作为行间隔)。
//
测试通过 by g++3.4.2 和 vc++2005
1. Tree.h文件:
#ifndef
__TREE_H__
#define __TREE_H__
#include
#include
#include
struct Tree
{
friend std::istream& operator>>(
std::istream& is, Tree& tree );
friend std::ostream&
operator<<( std::ostream& os, const Tree& tree );
typedef std::vector
static const char
Split;
Tree();
explicit Tree( const std::string nodename );
void
swap( Tree& tree );
std::string name;
sctype subs;
};
inline void swap( Tree& lhs, Tree& rhs )
{
lhs.swap( rhs
);
}
#endif // __TREE_H__
2.
Tree.cpp文件:
#include "Tree.h"
#include
using
namespace std;
const char Tree::Split = '\t';
Tree::Tree()
{
}
Tree::Tree( const string nodename ) :
name(nodename)
{
}
void Tree::swap( Tree& tree )
{
name.swap( tree.name );
subs.swap( tree.subs );
}
istream& operator>>( istream& is, Tree& tree )
{
struct parse
{
void operator()( const string& line,
size_t& level, string& name )
{
const char*
whitespace = " \t\n";
level = line.find_first_not_of( Tree::Split
);
if( level == string::npos ) level =
line.size();
size_t n1 = line.find_first_not_of( whitespace,
level );
if( n1 == string::npos )
{
name.erase();
}
else
{
size_t n2 = line.find_last_not_of(
whitespace );
name = line.substr( n1, n2-n1+1
);
}
}
} parse;
if( is.fail() ) return is;
tree = Tree();
typedef vector
COLS cols;
streampos
prepos;
for( string line; prepos=is.tellg(), getline(is,line); )
{
size_t level;
string name;
parse( line,
level, name );
if( name.empty() && tree.name.empty()
&& (is.flags() & is.skipws) )
{
continue;
}
if( name.empty() || level>cols.size() || (
level==0 && !tree.name.empty() ) )
{
is.seekg(
prepos );
if( tree.name.empty() )
is.setstate(
ios::failbit );
return is;
}
cols.resize(
level+1 );
if( level == 0 )
{
tree.name =
name;
cols.back() = &tree;
}
else
{
COLS::reverse_iterator b =
cols.rbegin();
COLS::reverse_iterator a = b; ++a;
(*a)->subs.push_back( Tree(name) );
(*b) =
&(*a)->subs.back();
}
}
if( !is.bad() &&
is.eof() && !tree.name.empty() )
is.clear();
return
is;
}
ostream& operator<<( ostream& os, const Tree& tree
)
{
os << tree.name << '\n';
size_t level =
1;
typedef
pair
vector
for( ; ; )
{
if( cols.back().first ==
cols.back().second )
{
--level;
cols.pop_back();
if( level == 0 ) break;
++cols.back().first;
}
else
{
os
<< setw((streamsize)level) << setfill(Tree::Split) << ""
<< cols.back().first->name << '\n';
++level;
cols.push_back(
COL(cols.back().first->subs.begin(),cols.back().first->subs.end())
);
}
}
return os;
}
3.
测试文件:
#include "Tree.h"
#include
#include
using namespace std;
int main( int argc, char *argv[] )
{
ifstream file( "test.txt"
);
for( Tree tree; file>>tree; cout<
file.clear();
for( string
line; getline(file,line); cout<
return
EXIT_SUCCESS;
}
test.txt文件内容:
a
b
c
dm
e
f
a2
b
c
"test"
e
f
输出:
a
b
c
dm
e
f
a2
b
c
"test"
-------------
e
f