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

Как связать несколько output потоков? - C++

Восстановить пароль Регистрация
 
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
17.03.2010, 18:54     Как связать несколько output потоков? #1
Можно ли создать поток, который будет связан с несколькими потоками, что-бы при записи в него производиласт запись и во все связаные потоки. К примеру, в следующем коде хотелось-бы что-бы результат не только был записан в файл, но и выведен на екран, можно конешто продублировать код, но если мне надо будет записать ето еще кудато, тогда что, создать еще поток и еще раз продублировать? А если мне надо будет что-то менять?
Code
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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <stdint.h>
 
typedef int64_t LL;
typedef std::vector<int> VI;
#define FOR(i,a,b) for(int i(a), _n(b); i < _n; ++i)
#define sz size()
 
const LL base = 1000*1000*1000;
 
VI operator *= (VI &a, VI &b)
{
    VI res(a.sz+b.sz);
    FOR(i,0,a.sz)
        for (int j = 0, carry = 0; j < b.sz || carry; ++j)
        {
            LL cur = res[i+j] + carry + a[i] * LL(j < b.sz ? b[j] : 0);
            res[i+j] = cur % base;
            carry = cur / base;
        }
    while (res.sz > 0 && !res.back()) res.pop_back();
    a = res;
    return a;
}
 
VI BinPow(int a, int n)
{
    VI res(1, 1), b(1, a);
    while (n)
        if (n&1) --n, res *= b;
        else n >>= 1, b *= b;
    return res;
}
 
int main()
{
    int a, n;
    clock_t begin, end;
    try
    {
        std::cin >> a >> n;
        if (a < 0 || n < 0) throw "Wrong input";
        begin = clock();
        VI res = BinPow(a, n);
        end = clock();
        
        std::ofstream file("output.txt");
        if (!file.good()) throw "Cann't open file.";
        
        file << a << "^" << n << "\n\n" << res.back();
        file.fill('0'), file.width(9);
        for (int i = res.sz-2; i > -1; --i)
            file << res[i];
        file << "\n\n" << "BinPow time: " << end - begin << " milisecond" <<
            ((end - begin < 2) ? "" :  "s") << std::endl;
    }
    catch (const char *event)
    {
        std::cout << event << std::endl;
    }
    system("pause");
}


Словом, вопрос - это название этой темы, как звязать несколько выходных потоков.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
17.03.2010, 20:25     Как связать несколько output потоков? #2
Этот пример не в самом лучшем стиле, но основная идея понятна:
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
class MultiStream{
public:
    std::vector<std::ostream*> streams;
    ~MultiStream();
    template<typename T> operator << (const T& value)
    {
        for(int i=0; i<streams.size(); ++i)
            (*(streams[i])) << val;
    }
};
 
MultiStream::~MultiStream()
{
    for(int i=0; i<streams.size(); ++i)
        delete streams[i];
}
 
int main()
{
    MultiStream s;
    s.streams.push_back(new std::ofstream("output.txt"));
    s.streams.push_back(&cout);
    s << 1 << "2";
    s.pop_back();
    return 0;
}
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
17.03.2010, 23:05  [ТС]     Как связать несколько output потоков? #3
Цитата Сообщение от Nick Alte Посмотреть сообщение
Этот пример не в самом лучшем стиле
почему не в самом лучшем стиле??

Добавлено через 32 минуты
Code
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
87
88
89
90
91
92
93
94
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <stdint.h>
 
typedef int64_t LL;
typedef std::vector<int> VI;
#define FOR(i,a,b) for(int i(a), _n(b); i < _n; ++i)
#define sz size()
 
const LL base = 1000*1000*1000;
 
VI operator *= (VI &a, VI &b)
{
    VI res(a.sz+b.sz);
    FOR(i,0,a.sz)
        for (int j = 0, carry = 0; j < b.sz || carry; ++j)
        {
            LL cur = res[i+j] + carry + a[i] * LL(j < b.sz ? b[j] : 0);
            res[i+j] = cur % base;
            carry = cur / base;
        }
    while (res.sz > 0 && !res.back()) res.pop_back();
    a = res;
    return a;
}
 
VI BinPow(int a, int n)
{
    VI res(1, 1), b(1, a);
    while (n)
        if (n&1) --n, res *= b;
        else n >>= 1, b *= b;
    return res;
}
 
class MultiStream
{
public:
    MultiStream() {  }
    ~MultiStream(){ FOR(i,0,stream.sz) delete stream[i]; }
    std::vector<std::ostream *> stream;
    void push(std::ostream *stream)
    {
        this->stream.push_back(stream);
    }
    void fill(const char s)
    {
        FOR(i,0,stream.sz) stream[i]->fill(s);
    }
    void width(const int n)
    {
        FOR(i,0,stream.sz) stream[i]->width(n);
    }
    template <class T> operator << (const T value)
    {
        FOR(i,0,stream.sz) *stream[i] << value;
    }
};
 
int main()
{
    int a, n;
    clock_t begin, end;
    try
    {
        std::cin >> a >> n;
        if (a < 0 || n < 0) throw "Wrong input";
        begin = clock();
        VI res = BinPow(a, n);
        end = clock();
        
        std::ofstream file("output.txt");
        if (!file.good()) throw "Cann't open file.";
        
        MultiStream MS;
        MS.push(&std::cout), MS.push(&file);
                
        MS << a << "^" << n << "\n\n" << res.back();
        MS.fill('0') , MS.width(9);
        for (int i = res.sz-2; i > -1; --i)
            MS << res[i];
        MS << "\n\n" << "BinPow time: " << (end - begin) << " milisecond";
        if (end - begin < 2) MS << " ";
        else MS << "s";
        MS << std::endl;
    }
    catch (const char *event)
    {
        std::cout << event << std::endl;
    }
    system("pause");
}
не пашет..

C:/Documents and Settings/Администратор/Рабочий стол/help.cpp:57: error: ISO C++ forbids declaration of `operator<<' with no type
C:/Documents and Settings/Администратор/Рабочий стол/help.cpp: In function `int main()':
C:/Documents and Settings/Администратор/Рабочий стол/help.cpp:80: error: invalid operands of types `int' and `const char[2]' to binary `operator<<'
C:/Documents and Settings/Администратор/Рабочий стол/help.cpp:84: error: invalid operands of types `int' and `const char[14]' to binary `operator<<'
C:/Documents and Settings/Администратор/Рабочий стол/help.cpp:87: error: no match for 'operator<<' in 'MS << std::endl'

В основном проблема в том, что не поддерживается "цепочный" вывод типа:
C++
1
MS << "some text" << 154 << 12.154 << 's' << std::endl;
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1331 / 864 / 50
Регистрация: 02.01.2009
Сообщений: 2,622
Записей в блоге: 1
18.03.2010, 01:43     Как связать несколько output потоков? #4
так попробуй..
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
#include <iostream>
#include <ostream>
#include <fstream>
#include <vector>
 
template <typename _Elem, typename _Traits>
class b_coutf_{
 
public:
    void push_back(std::basic_ostream<_Elem, _Traits> &rhs){
        _out.push_back(&rhs);
    }
    ~b_coutf_(){
        _out.clear();
    }
 
    template<typename T>
    friend b_coutf_ & operator << (b_coutf_ &lhs, const T& rhs){
        typename std::vector<std::basic_ostream<_Elem, _Traits>* >::iterator i;
        i = lhs._out.begin();
        for(; i != lhs._out.end(); ++i)
            (*(*i)) << rhs;
        return lhs;
    }
private:
    std::vector<std::basic_ostream<_Elem, _Traits>* > _out;
};
 
 
typedef b_coutf_<char, std::char_traits<char> > coutf_;
 
 
int main(){
 
    coutf_ coutf;
    std::ofstream file("file.txt");
    
    coutf.push_back(std::cout);
    coutf.push_back(file);
 
    coutf << "Testing...\n" << 123 << '\n';
 
    file.close();
 
    return 0;
}
http://codepad.org/JDqHebSn
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
18.03.2010, 20:46     Как связать несколько output потоков? #5
да очепятался, забыл поставить возвращаемое значение. Бывает...
C++
1
2
3
4
5
6
    template<typename T> MultiStream& operator << (const T& value)
    {
        for(int i=0; i<streams.size(); ++i)
            (*(streams[i])) << val;
        return *this;
    }
Yandex
Объявления
18.03.2010, 20:46     Как связать несколько output потоков?
Ответ Создать тему
Опции темы

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