Форум программистов, компьютерный форум CyberForum.ru

Наследование от ofstream и перегрузка << - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
14.07.2015, 14:36     Наследование от ofstream и перегрузка << #1
Добрый день, гуглил на английском языке, но ответа не попалось. Предыстория: некий объекта принимает в качестве параметра ссылку на ostream, куда подсовывается ofstream. Задача в том, что перед действием << требуется сделать дополнительные телодвижения, а точнее обработать данные, которые направляются на выход. Я вижу решение таким, что нужно наследоваться от ofstream и переопределить <<. как это правильно делается нагуглить не удалось. Буду рад приведенным примерам или ссылкам на статьи об этом. Спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,250
15.07.2015, 12:30     Наследование от ofstream и перегрузка << #21
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от ForEveR Посмотреть сообщение
не сложилось
вот вариант который работает (просто вываливаю все что идет в поток на экран)
C++
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//---------------------------------------------------------------------------
 
#pragma hdrstop
 
//---------------------------------------------------------------------------
#include <iostream>
#include <stdlib.h>
//---------------------------------------------------------------------------
class my_obj
{
public:
    void print(std::ostream &os)
    {
        os << 123 << std::endl;
    }
};
//---------------------------------------------------------------------------
class my_buf: public std::streambuf
{
private:
    std::string str;
    
protected:
    virtual int_type overflow(int_type __c = traits_type::eof())
    {
        str.append(1, traits_type::to_char_type(__c));
        return traits_type::not_eof(__c);
    }
 
    virtual int sync(void)
    {
        std::cout << str;
        str.clear();
        return 0;
    }
};
//---------------------------------------------------------------------------
class my_stream: public std::ostream
{
private:
    my_buf buf;
    
public:
    my_stream(void):
        std::ostream(0)
    {
        this->init(&buf);
    }
};
//---------------------------------------------------------------------------
 
#pragma argsused
int main(int argc, char* argv[])
{
    my_stream os;
    my_obj obj;
    obj.print(os);
    obj.print(os);
    obj.print(os);
    system("pause");
    return 0;
}
//---------------------------------------------------------------------------
Добавлено через 5 минут
пожалуй лучшая ссылка на эту тему из тех которые я перелопатил
http://www.mr-edd.co.uk/blog/beginners_guide_streambuf

Добавлено через 3 минуты
тут тоже есть кое-что
http://stdcxx.apache.org/doc/stdlibug/38-3.html#3832
http://stdcxx.apache.org/doc/stdlibug/39-2.html
http://stdcxx.apache.org/doc/stdlibug/39-3.html
но все вокруг да около и не в те ворота (у меня нифига не заработало), но может кто-то что-то найдет
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
15.07.2015, 13:23     Наследование от ofstream и перегрузка << #22
vxg, А вот за это спасибо. Про init я как-то не знал. Да и вообще статьи интересные.
C++
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <array>
#include <functional>
#include <algorithm>
 
class formatting_streambuf: public std::streambuf
{
   typedef std::function<std::string(const std::string&)> formatter_t;
public:
   formatting_streambuf(std::streambuf* buf, const formatter_t& formatter) : buffer_{}, buf_(buf), formatter_(formatter)
   {
      setp(buffer_.begin(), buffer_.end() - 1);
   }
protected:
   virtual int overflow(int_type c = traits_type::eof()) override
   {
      *pptr() = traits_type::to_char_type(c);
      format();
      return traits_type::not_eof(c);
   }
 
   virtual int sync() override
   {
      format();
      return 0;
   }
private:
   void format()
   {
      const std::string value(buffer_.begin(), pptr() - buffer_.begin());
      const std::string formatted = formatter_(value);
      buf_->sputn(formatted.c_str(), formatted.size());
      setp(buffer_.begin(), buffer_.end());
   }
 
   std::array<char, 1024> buffer_;
   std::streambuf* buf_;
   formatter_t formatter_;
};
 
class formatting_ostream : public std::ostream
{
   typedef std::function<std::string(const std::string&)> formatter_t;
public:
   formatting_ostream(std::ostream& stream, const formatter_t& formatter) : 
      stream_(stream), old_buf_(stream_.rdbuf()), streambuf_(old_buf_, formatter)
   {
      init(&streambuf_);
   }
private:
   std::ostream& stream_;
   std::streambuf* old_buf_;
   formatting_streambuf streambuf_;
};
 
class source
{
public:
   source(std::ostream& stream) : stream_(stream)
   {
   }
 
   void print()
   {
      stream_ << "HeLlO" << std::endl;
   }
private:
   std::ostream& stream_;
};
 
int main()
{
   auto to_lower = [](const std::string& v) -> std::string
   {
      std::string result;
      std::transform(v.begin(), v.end(), std::back_inserter(result), tolower);
      return result;
   };
   formatting_ostream stream(std::cout, to_lower);
   source s(stream);
   s.print();
   s.print();
 
   source ss(std::cout);
   ss.print();
}
Добавлено через 6 минут
Пример работы
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
15.07.2015, 14:11  [ТС]     Наследование от ofstream и перегрузка << #23
Вот, красота! Благодарен за помощь, если увижу в личке номера телефонов вас обоих - немного пополню баланс

п.с. отсутствие виртуальности где хотелось бы, конечно, удручает((( похоже пора срочно отвыкать от Java-подобного... или же наоборот никогда его от себя не отпускать...
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,250
15.07.2015, 14:33     Наследование от ofstream и перегрузка << #24
Цитата Сообщение от ForEveR Посмотреть сообщение
Да и вообще
а для чего old_buf_ я не разобрался.. про запас)?
Цитата Сообщение от VVildVVolf Посмотреть сообщение
отсутствие виртуальности
о какой виртуальности речь
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
15.07.2015, 14:46  [ТС]     Наследование от ofstream и перегрузка << #25
Ну как в Java, где практически любой метод можно переопределить (если он явно от этого не защищен). Но возможно это негодование только от незнания специфики языка

Добавлено через 7 минут
Кстати, теперь можно прокидывать для вывода другой ostream и делать многоступенчатую обработку =D
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,250
15.07.2015, 14:50     Наследование от ofstream и перегрузка << #26
Цитата Сообщение от VVildVVolf Посмотреть сообщение
практически любой метод можно переопределить
ну и здесь можно любой метод переопределить если это технически было заложено в класс. просто STL так спроектирована что пришлось переопределять не то что в начале хотелось бы переопределить (хотелось переопределить << а пришлось лезть в буфера)

Добавлено через 1 минуту
спасибо за мотивацию!
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
15.07.2015, 14:52  [ТС]     Наследование от ofstream и перегрузка << #27
Вот я и говорю, что надеюсь, что в плюсах сделать можно всё (пусть и неочевидным с первого раза) красивым и объектно-ориентированным способом))

на здоровье, мне не жалко за дело) надеюсь что таки меня возьмут на работу с вашей помощью ..
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
15.07.2015, 14:57     Наследование от ofstream и перегрузка << #28
Цитата Сообщение от vxg Посмотреть сообщение
а для чего old_buf_ я не разобрался.. про запас)?
old_buf_ остался от того использования, когда я rdbuf у переданного стрима заменял. Сейчас можно просто послать stream_.rdbuf() в конструктор streambuf_. Нужен он, чтобы итоговая запись отформатированного текста ушла в нужный буфер.
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 09:58  [ТС]     Наследование от ofstream и перегрузка << #29
Привет всем снова, тут проблема возникла, при передачи в CustomStreamBuf ссылки на ostream. Передаю туда cout - всё норм, всё выводит на консоль, передаю туда ofstream - пустой файл получаю... из-за чего такое может быть?

и заодно ещё почему-то файл не хочет создаваться вообще, если прописать вместо "out.txt" что-нить типа "/output/out.txt", т.е. во вложенной папке. где-то на этом форуме была тема про такое создание выходного поток, народ пишет что файл должен создаваться во вложенной папке... у меня не создаётся, даже если эту папку сам создам...
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,250
20.07.2015, 12:30     Наследование от ofstream и перегрузка << #30
Цитата Сообщение от VVildVVolf Посмотреть сообщение
тут проблема
у меня работает
C++
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//---------------------------------------------------------------------------
 
#pragma hdrstop
 
//---------------------------------------------------------------------------
#include <iostream>
#include <fstream>
#include <stdlib.h>
//---------------------------------------------------------------------------
class my_obj
{
public:
    void print(std::ostream &os)
    {
        os << 123 << std::endl;
    }
};
//---------------------------------------------------------------------------
class my_buf: public std::streambuf
{
private:
    std::ostream *ptr;
public:
    my_buf(std::ostream &os): ptr(&os) {}
private:
    std::string str;
    
protected:
    virtual int_type overflow(int_type __c = traits_type::eof())
    {
        str.append(1, traits_type::to_char_type(__c));
        return traits_type::not_eof(__c);
    }
 
    virtual int sync(void)
    {
        *ptr << str;
        str.clear();
        return 0;
    }
};
//---------------------------------------------------------------------------
class my_stream: public std::ostream
{
private:
    my_buf buf;
    
public:
    my_stream(std::ostream &os):
        std::ostream(0),
        buf(os)
    {
        this->init(&buf);
    }
};
//---------------------------------------------------------------------------
 
#pragma argsused
int main(int argc, char* argv[])
{
    std::ofstream fos("12/out.txt");
    my_stream os(fos);
    my_obj obj;
    obj.print(os);
    obj.print(os);
    obj.print(os);
    system("pause");
    return 0;
}
//---------------------------------------------------------------------------
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
20.07.2015, 12:41     Наследование от ofstream и перегрузка << #31
Цитата Сообщение от VVildVVolf Посмотреть сообщение
Привет всем снова, тут проблема возникла, при передачи в CustomStreamBuf ссылки на ostream. Передаю туда cout - всё норм, всё выводит на консоль, передаю туда ofstream - пустой файл получаю... из-за чего такое может быть?
std::endl при выводе используется? Если нет - работать не будет.
Мой код тот же, кроме fstream:

C++
1
2
   std::ofstream ofs("test_file.txt");
   formatting_ostream stream(ofs, to_lower);
Bash
1
2
3
4
cat test_file.txt 
hello
hello
HeLlO
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,250
20.07.2015, 13:07     Наследование от ofstream и перегрузка << #32
Цитата Сообщение от ForEveR Посмотреть сообщение
Если нет - работать не будет
о ужас %/ зачем они сделали синк по эндл?? можно победить сделав руками флэш. ну или в оверфлоу ловить делители
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 13:12  [ТС]     Наследование от ofstream и перегрузка << #33
на самом деле синк в моём конкретно случае мало волнует (не бейте меня, я его в деструкторе стрима вызываю...), и получается endl и '\n' не одно и тоже? попробую в конце принудительно заталкивать endl для верности... но при указании папки - так ничего не создаётся, ни на домашнем ноуте, ни на рабочей машинке, даже при запуске с правами админа...
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,250
20.07.2015, 13:45     Наследование от ofstream и перегрузка << #34
Цитата Сообщение от VVildVVolf Посмотреть сообщение
я его в деструкторе стрима вызываю
так тоже можно. странно что он сам не вызывается. или может он вызывается но после того как поток файла убился. я всегда думал что эндл это просто вставка платформозависимого делителя. но наверное она еще и синк зовет. хз. зачем вам пихать эндл если все работает? или все еще не работает? у меня файл создается - почему у вас нет? может не нужно / ставить в голову?
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 13:52  [ТС]     Наследование от ofstream и перегрузка << #35
Цитата Сообщение от vxg Посмотреть сообщение
или все еще не работает
не работает на 2х машинах причем файл не создаётся, и со слэшем, и без, и с "~/" и с "./" и всё тоже самое с обратными слэшами пробовал..

причем (если файл создаётся в той же папке, что и прога) такой код:
C++
1
2
3
4
5
6
7
ofstream output;
    output.open(outFileName);
 
    output<<"begin"<<endl;
    
    p = new Parser(output);
    output<<"end"<<endl;
генерит файл с текстом
begin
end
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,250
20.07.2015, 14:03     Наследование от ofstream и перегрузка << #36
Цитата Сообщение от VVildVVolf Посмотреть сообщение
не работает
попробуйте абсолютный путь. может у вас рабочая папка какая-нибудь экзотическая при вызове
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 14:15  [ТС]     Наследование от ofstream и перегрузка << #37
Цитата Сообщение от vxg Посмотреть сообщение
попробуйте абсолютный путь. может у вас рабочая папка какая-нибудь экзотическая при вызове
не, не даёт... это причем даже в отдельном проекте, где пытаюсь просто тупо в файл записать.

Добавлено через 8 минут
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <fstream>
 
using namespace std;
int main(){
    ofstream os2("C://lol/lout.txt");
    os2<<"tro"<<endl;
    os2.close();
    return 0;
}
вот это не создаёт файл ни по абсолютному, ни по относительному, только если тупо имя указать - в текущей и всё...
Avazart
20.07.2015, 14:21
  #38

Не по теме:

Цитата Сообщение от vxg Посмотреть сообщение
ои глаза! мои прекрасные глаза!! до сих пор не могу привыкнут к этим штукам. и никогда наверное не привыкну
Так же фигня, а уши уши ведь звучит как нецензурщина ....

vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,250
20.07.2015, 14:24     Наследование от ofstream и перегрузка << #39
Цитата Сообщение от VVildVVolf Посмотреть сообщение
вот это не создаёт файл ни по абсолютному, ни по относительному, только если тупо имя указать - в текущей и всё
ну вы же понимаете что это невозможно)

Добавлено через 50 секунд
полагаю что то с правами или хз чем но не с программой. что то мне подсказывает что вам нужно попробовать порабоать в винде
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.07.2015, 14:30     Наследование от ofstream и перегрузка <<
Еще ссылки по теме:

Перегрузка ifstream и ofstream? C++
C++ Перегрузка ifstream и ofstream для работы с файлами в little-endian формате?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
VVildVVolf
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
20.07.2015, 14:30  [ТС]     Наследование от ofstream и перегрузка << #40
Цитата Сообщение от vxg Посмотреть сообщение
ну вы же понимаете что это невозможно)
я чего-то в упор не вижу(я что-то делаю так, что при этом невозможно создать файл), или невозможен факт несоздования файла с папкой?Оо если второе - готов поспорить)

Добавлено через 55 секунд
Цитата Сообщение от vxg Посмотреть сообщение
полагаю что то с правами или хз чем но не с программой. что то мне подсказывает что вам нужно попробовать порабоать в винде
Вы хотели сказать НЕ в винде?

Добавлено через 2 минуты
да и если б была проблема с правами,тогда б и в своей директории не разрешал создавать? я ведь и из-под диска C с правами админа запускал...
Yandex
Объявления
20.07.2015, 14:30     Наследование от ofstream и перегрузка <<
Ответ Создать тему
Опции темы

Текущее время: 16:11. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru