Nico Schumann
Nico Schumann

Reputation: 45

How to overload std::ofstream::put()?

I want to write int16_t values to file.

Therefore I tried to overload the std::ofstream::put() method.

#include <fstream>
#include <cstdint>

class Ofstream : public std::ofstream
{
public:
    Ofstream( const std::string & s) : std::ofstream(s) {}

    // for little-endian machines
    Ofstream & put(int16_t val)
    {
        char lsb, msb;
        lsb = (char)val;
        val >>= 8;
        msb = (char)val;
        put(lsb) && put(msb);
        return *this;
    }
    ~Ofstream() {}
};
int main()
{
    int16_t val = 0x1234;
    Ofstream ofile( "test");
    ofile.put(val);
}

At this I always get a Segmentation fault, so what's wrong with?

Upvotes: 3

Views: 180

Answers (2)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

The main problems with your code (infinite recursive calls), were already answered correctly.

Using explicit scoping like

std::ofstream::put(lsb) && std::ofstream::put(msb);

will fix this.

I want to write int16_t values to file.

Though I am under the impression that you want to write binary numbers in network byte order (big endian) to the file, and not put characters as text, and that's not what you're finally trying to achieve.

Here's how I would approach that (independently of the current machine architecture):

#include <fstream>
#include <arpa/inet.h>

struct Ofstream {
    std::ofstream os;

    Ofstream( const std::string & s) : os(s,std::ios_base::binary) {}

    void put(uint16_t dt) {
        uint16_t netdt = htons(dt);
        os.write((char*)&netdt,sizeof(netdt))
    }
};

int main() {
    uint16_t val = 0x1234;
    Ofstream ofile("test");
    ofile.put(val);
}

In general it's not a good idea to inherit from standard library classes unless they are explicitely intended to do so for implementation (i.e. std::ostream).
Rather use them as member variables.

Upvotes: 1

Sid S
Sid S

Reputation: 6125

Your put() function calls itself rather than the base class version. So you get infinite recursion, which leads to stack overflow.

Replace

put(lsb) && put(msb);

with

std::ofstream::put(lsb) && std::ofstream::put(msb);

Upvotes: 1

Related Questions