CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Apr 2005
    Posts
    125

    Unhappy Writing structures of vectors / std::string into binary file

    Hi,

    I am using the following structures

    struct KeyValPair
    {
    std::string Key;
    std::string Value
    };

    struct Properties
    {
    std::string PropertyName;
    vector <KeyValPair > PropVal;
    };

    struct MainComponent
    {
    std::string MainName;
    vector < Properties > Properties;
    };

    Now in my mail program, I have defined

    vector < MainComponent > objComponent;

    and I am storing say 10 components values inside this one.
    I want these values of the 10 components the next time I execute the program. So the only option I have is to write to file as binary data right ??

    Can someone show me how this can be achieved ?

    I tried the FILE *fp; thingy and the fwrite and fread
    E.g.
    FILE*fp;
    fp = fopen("c:\\Component.dat","wb");
    fwrite(&objComponent,sizeof(objComponent),2,fp);

    But i am getting errors. I dont know how to fill parameters for the fwrite since it contains vectors which can be variable.

    I am forced to use only standard C++ libraries as this is part of a helper class for a bigger program.

    Please do help me.... I am also googling since morning but without much success..

    thanks in anticipation.

    Also i would be delighted if someone would post with code examples to my program.

  2. #2
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Writing structures of vectors / std::string into binary file

    You don't have to use FILE and probably shouldn't, as it's not really the "C++ way".You can use ofstream to write data to a file, and ifstream to read from a file.

    Code:
    std::ofstream stream;
    stream.open("test.txt");
    if(stream.fail())
    	throw std::runtime_error("Couldn't open test.txt.");
    stream << "blah";
    stream.close();
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  3. #3
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: Writing structures of vectors / std::string into binary file

    When you have non-POD data (example std::string), there is
    no easy way to read/write unformatted (binary). Basically, you
    need to do it individually for each data member. I have
    a few routines to aid in doing this. I can't post the actual codes,
    but I can post some slightly simplified versions (which I have
    not tested, but will give you an idea).

    A) First, to read/write binary std::strings:

    Code:
    bool WriteUnformatted_string(std::ostream & out , const std::string & s)
    {
        std::string::size_type n = s.size();
        out.write( reinterpret_cast<const char*>(&n) , sizeof(n) );
    
        if (n > 0)
        {
            out.write( s.c_str() , n );
        }
    
        return !out.bad();
    }
    
    
    bool ReadUnformatted_string(std::istream & in , std::string & s)
    {
        // Note : With the upcoming changes to the C++ standard,
        //        you will not need the intermediate vector, since
        //        a std::string will be gaurenteed to have
        //        contigous storage (at least, I saw that posted)
    
        std::string::size_type n;
        in.read( reinterpret_cast<char*>(&n) , sizeof(n) );
    
        if (n > 0)
        {
            std::vector<char> v(n);
            in.read( &v[0] , n );
            s.assign(&v[0],&v[0]+n);
        }
        else
        {
            s = "";
        }
    
        return !in.bad();
    }

    B) Next, to read/write unformatted non-POD vectors

    Code:
    template <typename T>
    bool WriteUnformatted_vector_nonPOD(std::ostream & out , const std::vector<T> & v)
    {
        size_t n = v.size();
    
        out.write( reinterpret_cast<char*>(&n) , sizeof(n) );
    
        for (int i =0; i<n; ++i)
        {
            v[i].WriteUnformatted(out);   // assumes a WriteUnformatted() member function
        }
    
        return !out.bad();
    }
    
    template <typename T>
    bool ReadUnformatted_vector_nonPOD(std::istream & in , std::vector<T> & v)
    {
        v.clear();
    
        size_t n;
    
        in.read( reinterpret_cast<char*>(&n) , sizeof(n) );
    
        if (n > 0)
        {
            T key_value;
    
            v.reserve(n);
            for (int i =0; i<n; ++i)
            {
                key_value.ReadUnformatted(in); // assumes a ReadUnformatted() member function
                v.push_back(key_value);
            }
        }
    
        return !in.bad();
    }
    C) Next modifying your classes

    Code:
    struct KeyValPair
    {
        std::string Key;
        std::string Value;
    
        bool WriteUnformatted(std::ostream & out) const
        {
            WriteUnformatted_string(out,Key);
            WriteUnformatted_string(out,Value);
    
            return !out.bad();
        }
    
    
        bool ReadUnformatted(std::istream & in)
        {
            ReadUnformatted_string(in,Key);
            ReadUnformatted_string(in,Value);
    
            return !in.bad();
        }
    };
    
    struct Properties
    {
        std::string PropertyName;
        std::vector <KeyValPair> PropVal;
    
        bool WriteUnformatted(std::ostream & out) const
        {
            WriteUnformatted_string(out,PropertyName);
            WriteUnformatted_vector_nonPOD(out,PropVal);
    
            return !out.bad();
        }
    
        bool ReadUnformatted(std::istream & in)
        {
            ReadUnformatted_string(in,PropertyName);
            ReadUnformatted_vector_nonPOD(in,PropVal);
    
            return !in.bad();
        }
    };
    
    struct MainComponent
    {
        std::string MainName;
        std::vector < Properties > Properties;
    
        bool WriteUnformatted(std::ostream & out) const
        {
            WriteUnformatted_string(out,MainName);
            WriteUnformatted_vector_nonPOD(out,Properties);
    
            return !out.bad();
        }
    
        bool ReadUnformatted(std::istream & in)
        {
            ReadUnformatted_string(in,MainName);
            ReadUnformatted_vector_nonPOD(in,Properties);
    
            return !in.bad();
        }
    };

    D) Note: you should open files using ios::binary mode

    E) None of this has been tested, but it should give you an
    idea of what needs to be done.
    Last edited by Philip Nicoletti; February 11th, 2009 at 09:37 AM.

  4. #4
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Writing structures of vectors / std::string into binary file

    I don't think the OP meant that the objects have to be written as binary data, rather that they were unsure if it was the only way to do it.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured