#include <string>
#include <sstream>
#include <iostream>

struct node
{
    node( const std::string& d, node* lc, node* rc )
        : data(d), left_child(lc), right_child(rc) {}

    ~node() { delete left_child ; delete right_child ; }

    std::string data ;
    node* left_child ; // unique owning pointer
    node* right_child ; // unique owning pointer

    private: node( const node& ) ; void operator= ( const node& ) ; // non-copyable
};

std::ostream& write( std::ostream& stm, node* tree )
{
    if(tree)
    {
        stm << tree->data << ' ' ;
        write( stm, tree->left_child ) ;
        return write( stm, tree->right_child ) ;
    }
    else return stm << "# " ;
}

node* make_tree( std::istream& stm )
{
    std::string data ;
    if( stm >> data && data != "#" )
    {
        /*auto*/ node* left_child = make_tree(stm) ;
        return new node( data, left_child, make_tree(stm) ) ;
    }
    else return 0 ;
}

int main()
{
    std::istringstream stm( "root aaa C # # D # # string 1231 # # #" ) ;
    /*auto*/node* tree = make_tree(stm) ;
    write( std::cout, tree ) << '\n' ;
    delete tree ;
}
