0

I have read How do you clear a stringstream variable? to clear the buffer by stringstream.str(""), or in other words - setting empty string. But if I do so, it won't clear it:

date.hpp:

#include <sstream>
#include <time.h>

#define fmt "%m/%d/%y"

class Date
{
    std::stringstream buffer;
    struct tm date;

    template <class T>
    void insertbuf(const T &);
    void inserttime();
    std::string getFromIn(std::istream &);

public:
    //ctors
    Date();
    Date(const char *str);
    Date(const std::string &s);
    Date(std::istream &in);
    Date(const Date &d);

    //operators
    Date &operator=(const Date &rhs);

    //general
    const std::string getAll() const;
    int getMonth() const;
    int getDay() const;
    int getYear() const;
};

date.cpp:

template <class T>
void Date::insertbuf(const T &val)
{
    if (!buffer.rdbuf()->in_avail())
    {
        buffer << val;
    }
}

void Date::inserttime()
{
    buffer >> std::get_time(&date, fmt);
}

Date &Date::operator=(const Date &rhs)
{
    if (&rhs != this)
    {
        buffer.str("");
        insertbuf<std::string>(rhs.buffer.str());
        inserttime();
    }
    return *this;
}

Now in function insertbuf, I will << to the buffer only if there is no other data. So in the operator=, which its left-hand-side (the object itself, or *this), has some data in the buffer and thus I have to clear them. I am trying to do so by setting the buffer to empty string buffer.str("") or equivalently buffer.str(std::string()), but it seems, that will not set it. From here:

main.cpp:

int main()
{
    Date bar = "11/23/2020";
    Date foo = "11/21/2020";
    cout << "before operator= " << foo.getAll() << endl;
    foo = bar;
    cout << "after operator= " << foo.getAll() << endl;
}

output:

before operator= date: 11/21/2020
after operator= date: 11/21/2020

As I can see the buffer was not cleared in the operator= function, because the buffer did not changed (The output should be 11/23/2020, the insertbuf function probably did not get over the if statement because the buffer was not empty, even though I set it to empty string), why? And how to properly clear the buffer of std::stringstream then?

An exmaple: https://godbolt.org/z/h6zofr

The reason, behind the question is here: https://codereview.stackexchange.com/questions/252456/how-to-implement-simple-date-class-in-c

milanHrabos
  • 2,010
  • 3
  • 11
  • 45

1 Answers1

2

The problem you are having is that calling buffer.str("") doesn't reset the stream state flags so if a previous operation failed or reached the end of the stream no other reads will succeed. The following should fix the issue:

buffer.str("");
buffer.clear();

Your code seems unnecessarily convoluted. If all you are trying to do is convert dates to and from strings I recommend using Howard Hinnant's date library which is now also part of c++20.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • It was just for learning purposes of implementing classes, I would use std-lib class for date in real project of course – milanHrabos Nov 21 '20 at 13:49
  • Anyway, I am not yet very familiar with streambuf to know, which its flags are important (otherwise I would not care about clear(), which clears the flags). You said, the previous operation failed. I see no place in the code, where I am creating object from `const char*`, where would the buffer of `stringstream` should fail. So why do I have to clear the flags, when in nowhere the buffer should not fail. Can you please explain? – milanHrabos Nov 21 '20 at 14:00
  • And also, in what place (line) from the main function does the buffer "reach the end of stream"? Where? (just to want to understand it) – milanHrabos Nov 21 '20 at 14:01
  • `inserttime` sets the `eof` and `fail` bits as your format string is incorrect (should be `%m/%d/%Y`), even with the corrected format string it still sets the `eof` flag as it reads to the end of the stream – Alan Birtles Nov 21 '20 at 14:48
  • The reason behind the question, is here – milanHrabos Nov 21 '20 at 14:50
  • https://codereview.stackexchange.com/questions/252456/how-to-implement-simple-date-class-in-c – milanHrabos Nov 21 '20 at 14:50