Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.58/26: Рейтинг темы: голосов - 26, средняя оценка - 4.58
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6

Как создать свой поток и связать его с консолью

07.03.2014, 10:41. Показов 5853. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Собственно возник такой вопрос: читаю Саттера пробую создать свой класс символов не чувствительный к регистру. Автор пишет, что для вывода на консоль требуется использовать поток со своим типом сравнения символов.
В классе basic_string определен оператор:
C++
1
2
3
4
  template<typename _CharT, typename _Traits, typename _Alloc>
    basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os,
           const basic_string<_CharT, _Traits, _Alloc>& __str);
Вопрос как создать объект типа basic_ostream<char, MyChar> (MyChar - мой тип сравнения символов) и связать его с консолью?
Для потока нашел только один открытый конструктор
C++
1
2
3
      explicit 
      basic_ostream(__streambuf_type* __sb)
      { this->init(__sb); }
Как его использовать?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.03.2014, 10:41
Ответы с готовыми решениями:

Создать свой поток данных
Не могу понять, возможно ли как то создать свой поток данных? Знаю есть файловые потоки, cin cout cerr, а как быть если мне нужен поток...

Как создать свой класс и подключить его в main?
я новичок,хотел поинтересоваться,когда люди пишут программу,они сначала главную функцию main пишут,а потом пишут классы и подключают к main...

В окне перемещаются объекты, отталкиваясь от стенок окна. Каждый объект имеет свой поток, перемещающий его. Встретившись, объекты начинают двигаться
В окне перемещаются объекты, отталкиваясь от стенок окна. Каждый объект имеет свой поток, перемещающий его. Встретившись, объекты...

13
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
07.03.2014, 11:45
а зачем его создавать?
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
07.03.2014, 11:48  [ТС]
Цитата Сообщение от aLarman Посмотреть сообщение
а зачем его создавать?
Потому, что в стандартный поток вывести свою строку я не могу.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
07.03.2014, 12:04
я может быть чего то не понял но попробую предложить, если нужен класс не чувствительных к регистру символов, то их нужно приводить к одному их регистров (нижний или верхний)
вот набросал
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 CharNorReqister
{
public:
    CharNorReqister(char InX)
    {
        x = tolower(InX);
    }
    CharNorReqister():x(0)
    {
 
    }
    friend istream & operator>>(istream & is, CharNorReqister & X)
    {
        char a;
        is >> a;
        X.x = tolower(a);
        return is;
    }
    friend ostream & operator<<(ostream & os, CharNorReqister & X)
    {
        os << X.x;
        return os;
    }
private:
    char x;
};
дальше доопределить методы сравнений и операторы, или это не то?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
07.03.2014, 12:07
Ilot,
C++
1
2
std::streambuf * buf = std::cout.rdbuf();
std::ostream out(buf);
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
07.03.2014, 12:07  [ТС]
Цитата Сообщение от aLarman Посмотреть сообщение
или это не то?
Не то.
Есть класс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct MyChar: public std::char_traits<char> {
    static bool
    eq(const char_type& __c1, const char_type& __c2)
    { return toupper(__c1) == toupper(__c2); }
 
    static bool
    lt(const char_type& __c1, const char_type& __c2)
    { return toupper(__c1) < toupper(__c2); }
    static int
    compare(const char_type* __s1, const char_type* __s2, size_t __n)
    { return memicmp(__s1, __s2, __n); }
    /*
    static const char_type*
    find(const char_type* __s, size_t __n, const char_type& __a)
    { return static_cast<const char_type*>(memchr(__s, __a, __n)); }
    */
};
 
//std::basic_ostream<char, MyChar> mcout;
typedef std::basic_string<char, MyChar> ci_string;
Надо сделать, что бы работало такое выражение:
C++
1
mcout << ci_string;
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
07.03.2014, 12:13
aLarman, он хочет через Traits.

Добавлено через 5 минут
Да, кстати придется делать и свой streambuf.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
07.03.2014, 12:41
примерчик
1
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
07.03.2014, 14:53  [ТС]
Tulosba, благодарю, однако вывести в стандартный поток это не проблема. Сложно ли создать свой поток и связать его с консолью, раз такая возможность предусмотренна в стандартной библиотеке и как это сделать? Вот собственно в чем вопрос.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
07.03.2014, 15:08
Цитата Сообщение от Ilot Посмотреть сообщение
Сложно ли создать свой поток и связать его с консолью
Так ведь DrOffset всё написал уже выше.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
class mystream : public std::ostream
{
public:
    mystream()
    {
        rdbuf( std::cout.rdbuf() );
    }
};
 
int main() {
 
    mystream m;
    m << "Hello\n";
 
    return 0;
}
http://ideone.com/uvNq9M

Конструктор можно сделать даже так:
C++
1
mystream() : std::ostream( std::cout.rdbuf() ) { }
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
07.03.2014, 15:09
Ilot, я ж говорю, наследуйся от basic_streambuf (если хочешь собственный Traits, то streambuf от stdcout не подойдет, т.к. привязан к его Traits).
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
11.03.2014, 14:49  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Ilot, я ж говорю, наследуйся от basic_streambuf (если хочешь собственный Traits, то streambuf от stdcout не подойдет, т.к. привязан к его Traits).
Я знаю что cout не подойдет, поэтому и создал тему. Однако если файловый поток создать это как два пальца:
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <string.h>
#include <fstream>
struct MyChar: public std::char_traits<char> {
    static bool
    eq(const char_type& __c1, const char_type& __c2)
    { return toupper(__c1) == toupper(__c2); }
 
    static bool
    lt(const char_type& __c1, const char_type& __c2)
    { return toupper(__c1) < toupper(__c2); }
    static int
    compare(const char_type* __s1, const char_type* __s2, size_t __n)
    { return memicmp(__s1, __s2, __n); }
};
//std::basic_ostream<char, MyChar> mcout;
typedef std::basic_string<char, MyChar> ci_string;
int main()
{
    std::basic_ofstream<char, MyChar> mfout;
    mfout.open("C:\\rt.txt");
    ci_string str1("Masha");
    mfout << str1;
    return 0;
}

,то с созданием потока завязанного на консоль возникают определенные трудности. Понятно, что нужно создавать поток и передавать ему указатель на потоковый буфер, но вот так
C++
1
std::streambuf * buf = std::cout.rdbuf();
это сделать нельзя так как у меня должен быть буфер типа:
basic_streambuf<char, MyChar>
Интересно, а где создается объект cout? В заголовочниках нашел только:
C++
1
  extern ostream cout;
и ни одного намека на то где искать определение самого объекта.
Почитал немного о системном программировании в Win. Там пишут, что при создании консольного приложения для него создаются соответствующие потоки ввода/вывода. Другими словами выходит, что бы изменить поток вывода в консоль нужно юзать функции апи, а не стандартной библиотеки?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
11.03.2014, 18:46
Цитата Сообщение от Ilot Посмотреть сообщение
это сделать нельзя так как у меня должен быть буфер типа:
basic_streambuf<char, MyChar>
Так ведь я же и говорю, что нужно сделать свой streambuf, который бы соответствовал твоему traits.
Надо отнаследоваться от basic_streambuf<char, MyChar>, подробности можно посмотреть тут.

Цитата Сообщение от Ilot Посмотреть сообщение
Интересно, а где создается объект cout?
Внутри С++ runtime.

Добавлено через 18 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class console_buffer
    : public std::basic_streambuf<char, MyChar>
{
//......
};
 
int main()
{
    console_buffer conBuf;
    std::basic_ostream<char, MyChar> conOut(&conBuf);
 
    conOut << "test";
}
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
14.04.2014, 19:51
Ilot,
Ну вот как-то так может выглядеть реализация:
Кликните здесь для просмотра всего текста
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <streambuf>
#include <limits>
#include <cstdio>
 
class console_buffer
    : public std::basic_streambuf< char, std::char_traits<char> >
{
public:
    explicit console_buffer(FILE * file)
        : file_(file)
    {}
 
    ~console_buffer()
    {
        std::fflush(file_);
    }
 
protected:
    std::basic_streambuf<char, std::char_traits<char> > * setbuf(char * s, std::streamsize n)
    {
        size_t n_size_t = sizeof(std::streamsize) > sizeof(size_t)
                          ? static_cast<size_t>(
                                std::min(
                                    static_cast<std::streamsize>(std::numeric_limits<size_t>::max())
                                  , n
                                )
                            )
                          : static_cast<size_t>(n);
        std::setvbuf(file_, s, s == 0 && n == 0 ? _IONBF : _IOFBF, n_size_t);
        return this;
    }
 
    pos_type seekoff(off_type off
                     , std::ios_base::seekdir dir
                     , std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
    {
        int whence;
        switch(dir)
        {
        case std::ios_base::beg:
            whence = SEEK_SET;
            break;
        case std::ios_base::cur:
            whence = SEEK_CUR;
            break;
        case std::ios_base::end:
            whence = SEEK_END;
            break;
        default:
            return pos_type(-1);
        }
        if(off <= std::numeric_limits<off_type>::max() && std::fseek(file_, off, whence) == 0)
        {
            std::fpos_t pos;
            std::fgetpos(file_, &pos);
            return pos_type(pos);
        }
        return pos_type(-1);
    }
 
    pos_type seekpos(pos_type pos
                     , std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
    {
        std::fpos_t p(pos);
        return std::fsetpos(file_, &p) == 0 ? pos : pos_type(-1);
    }
 
    int sync()
    {
        return std::fflush(file_) == 0 ? 0 : -1;
    }
 
    std::streamsize showmanyc()
    {
        return -1;
    }
 
    int_type overflow(int_type c = traits_type::eof())
    {
        if(c == traits_type::eof())
        {
            std::ptrdiff_t unwritten = this->pptr() - this->pbase();
            if(unwritten != 0)
            {
                std::fflush(file_);
                if(this->pptr() - this->pbase() < unwritten)
                {
                    return traits_type::not_eof(c);
                }
                return traits_type::eof();
            }
            return traits_type::not_eof(c);
        }
        else
        {
            int result = putc(c, file_);
            return result != EOF ? result : traits_type::eof();
        }
    }
 
private:
    FILE * file_;
};
 
#include <ostream>
 
int main()
{
    console_buffer conBuf(stdout);
    std::basic_ostream<char, std::char_traits<char> > conOut(&conBuf);
 
    conOut << "TeSt";
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.04.2014, 19:51
Помогаю со студенческими работами здесь

Нужно создать базу данных (создать пустой бинарный файл). Через поток. Поток бинарного файла описать в виде локальной переменной внутри функции.
Совсем не понял эту тему. Нужно создать базу данных (создать пустой бинарный файл). Через поток. Поток бинарного файла описать в виде...

Как создать свой Toolbox, точнее на подобии его?
Здравствуйте. Скажите пожалуйста, как создать свой Toolbox, точнее на подобии его? Не пойму как он правильно называется, чтобы найти...

Как создать свой тип файлов и ассоциировать его со своим приложением
Например, AutoCAD .dwg и т.п. Заранее спасибо)

Как с помощью Enum создать список областей в родительском классе и связать его с базовым
Скажите как с помощью Enum создать список областей в родительском классе и связать его с базовым? using System; using...

Вызывающий поток не может получить доступ к объекту, так как его владельцем является другой поток
Есть форма MainWindo, есть класс AB. В форме единая точка доступа к элементам формы. public static MainWindow Forma = null; ...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru