How to specify an OutputIterator (in bibtex-spirit)

I am using bibtex-spirit to read a bibtex file.

All works fine (installed okay, on top of Boost 1.53.0) and I can read the bibtex entries okay (confirmed by inspecting in debug mode).

I have two questions:

Q. 1
====
Being a C++ newbie, I am not sure what to supply to the write function if (for example) I want to write to the screen (e.g. the equivalent of 'cout << entry << endl') or how do I write the output to a string or file?

The definition of the the write function is given as

template<class OutputIterator>
bool write(OutputIterator out, const BibTeXEntry& e);

template<class E, class T>
bool write(std::basic_ostream<E, T>& out, const BibTeXEntry& e);

template<class E, class T>
std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& out, const BibTeXEntry& entry);

Q. 2
====
(which might be answered if I can get question 1 to work)

The reason I am using bibtex-spirit is to try saving writing a parser to format author names. Will bibtex-spirit do this formatting, or will it simply output what it reads?


The code I am using is as follows
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <fstream>
#include <vector>

#include "bibtexentry.hpp"
#include "bibtexreader.hpp"
#include "bibtexwriter.hpp"

int main() {
  ifstream in("AOR-2011.bib");
  bibtex::BibTeXEntry entry;
  read(in, entry);
  // I want to say 'write(OutputIterator, entry)' here?????
  // but not sure what to pass to the OutputIterator parameter????
}


Thx

G
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main() {
  ifstream in("AOR-2011.bib");
  bibtex::BibTeXEntry entry;
  read(in, entry);

  // I want to say 'write(OutputIterator, entry)' here?????
  // but not sure what to pass to the OutputIterator parameter????
  
  write( std::ostream_iterator<char>( std::cout ), entry ) ;
  
  // or, simpler
  write( std::cout, entry ) ; 

  // or, simplest
  std::cout << entry ;
}
Thanks

I had tried things like this.

When I try

 
write( std::ostream_iterator<char>( std::cout ), entry ) ;


or

 
std::cout << entry ;


I get

d:\dropbox\projects\classes\boost\boost_1_53_0\boost\spirit\home\karma\char\char.hpp(276): error C2664: 'boost::mpl::assertion_failed' : cannot convert parameter 1 from 'boost::mpl::failed ************(__thiscall boost::spirit::karma::char_set<CharEncoding,Tag,no_attribute>::{ctor}::cannot_convert_string::* ***********)(T [])' to 'boost::mpl::assert<false>::type'
1> with
1> [
1> CharEncoding=boost::spirit::char_encoding::standard_wide,
1> Tag=boost::spirit::unused_type,
1> no_attribute=false,
1> T=const char
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
1> d:\dropbox\projects\classes\boost\boost_1_53_0\boost\spirit\home\karma\char\char.hpp(436) : see reference to function template instantiation 'boost::spirit::karma::char_set<CharEncoding,Tag,no_attribute>::char_set<T[3]>(String (&))' being compiled


....... [lots more] ..........



1>Build FAILED.



When I try

 
write( std::cout, entry ) ;


I get

c:\program files (x86)\microsoft visual studio 10.0\vc\include\ostream(604): error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\ios(176) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> This diagnostic occurred in the compiler generated function 'std::basic_ostream<_Elem,_Traits>::basic_ostream(const std::basic_ostream<_Elem,_Traits> &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1>
1>Build FAILED.


Any other ideas/suggestions?

Thx

G


OutputIterator is any iterator you can write to. It could be v.begin() from a sufficiently large vector, it could be back_inserter(str) made from a string, it could be ostream_iterator as JLBorges showed, etc.

I downloaded bibtex-spirit from http://bitbucket.org/sergiu/bibtex-spirit/ and I see the same errors from the write() function, both when compiling against boost-1.53 and when compiling against boost-1.46 which that library was written for. I think the author simply didn't finish this part: there are tests for the read() function in parse/main.cpp, but the test file for the write() (generate/main.cpp) is empty.
Many thanks - back to the drawing board :-)
Looking at the source (bibtexentry.hpp), rolling out a function of your own appears to be fairly straightforward.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <string>
#include <vector>
#include <boost/operators.hpp>
#include <boost/optional.hpp>
#include <iostream>

namespace bibtex
{
    typedef std::vector<std::string> ValueVector;
    typedef std::pair<std::string, ValueVector> KeyValue;
    typedef std::vector<KeyValue> KeyValueVector;

    struct BibTeXEntry : boost::equality_comparable<BibTeXEntry>
    {
        //! Entry's tag.
        std::string tag;
        //! Entry's optional key.
        boost::optional<std::string> key;
        //! Entry's key/value pairs.
        KeyValueVector fields;
    };

    std::ostream& to_stream( const BibTeXEntry& entry, std::ostream& stm )
    {
        static const auto quote = [] ( const std::string& str ) { return '"' + str + '"' ; } ;
        stm << "tag: " << quote(entry.tag) << '\n'
            << "key: " << ( entry.key ? quote(*entry.key) : "none" ) ;
        for( const auto& kv : entry.fields )
        {
            stm << "\n  field: " << quote(kv.first) << "  values:" ;
            for( const auto& v : kv.second ) stm << ' ' << quote(v) ;
        }
        return stm << '\n' ;
    }
}

int main()
{
    bibtex::BibTeXEntry entry ;
    to_stream( entry, std::cout ) << '\n' ;

    entry.tag = "the tag" ;
    entry.fields = { { "one", { "two", "three", "four" } }, { "5", { "6", "7" } },
                     { "eight", { "nine", "ten", "eleven", "twelve" } } } ;
    to_stream( entry, std::cout ) << '\n' ;

    entry.key = "the key" ;
    to_stream( entry, std::cout ) << '\n' ;
}
Ahh - okay. I'll give that a try. Many thanks. G
Topic archived. No new replies allowed.