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

Признак окончания потока для буферного итератора - C++

Восстановить пароль Регистрация
 
 
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
11.04.2014, 13:44     Признак окончания потока для буферного итератора #1
Собственно надоело вводить ctrl+z для ввода признака окончания потока, засим возник вопрос а возможно ли изменить этот самый признак для буферного итератора?
Взглянул на заголовочники - узрел эти конструкторы:
C++
1
2
3
4
5
6
7
8
9
10
11
      ///  Construct end of input stream iterator.
      istreambuf_iterator() throw()
      : _M_sbuf(0), _M_c(traits_type::eof()) { }
 
      ///  Construct start of input stream iterator.
      istreambuf_iterator(istream_type& __s) throw()
      : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
 
      ///  Construct start of streambuf iterator.
      istreambuf_iterator(streambuf_type* __s) throw()
      : _M_sbuf(__s), _M_c(traits_type::eof()) { }
Таким образом получается необходимо что бы traits_type::eof() возвращало к примеру '\n' и что бы все это работало со стандартными потоками. Как бы это сделать?
(traits_type это шаблон char_traits)

Добавлено через 2 часа 10 минут
Неужели задача такая сложная?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
11.04.2014, 14:44
  #2

Не по теме:

Цитата Сообщение от Ilot Посмотреть сообщение
Неужели задача такая сложная?
А зачем Вы о ней спрашиваете тогда?

Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
11.04.2014, 15:02  [ТС]     Признак окончания потока для буферного итератора #3
Tulosba, ну очень смешно.
Пытался написать свой тип от char_traits, но вовремя понял, что ни к чему хорошему это не приведет.
EOF запрятан где-то очень глубоко в заголовочниках и как на него повлиять неизвестно.
Есть ли другой путь?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.04.2014, 16:02     Признак окончания потока для буферного итератора #4
Цитата Сообщение от Ilot Посмотреть сообщение
Есть ли другой путь?
Для чего? Чтобы не вводить ctrl+z для ввода признака окончания потока? Пример кода приведите.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
14.04.2014, 09:06  [ТС]     Признак окончания потока для буферного итератора #5
Цитата Сообщение от alsav22 Посмотреть сообщение
Для чего? Чтобы не вводить ctrl+z для ввода признака окончания потока?
Да, да именно для этого.
Цитата Сообщение от alsav22 Посмотреть сообщение
Пример кода приведите.
Если бы я мог привести пример кода то не задавал бы такой вопрос. А вообще-то вопрос можно перефразировать так - как заставить вот такую конструкцию завершать ввод при вводе '\n':
C++
1
std::copy(std::istreambuf_iterator<char>(std::cin), std::istreambuf_iterator<char>(), back_inserter(Container));
newbie666
Заблокирован
14.04.2014, 09:20     Признак окончания потока для буферного итератора #6
Цитата Сообщение от Ilot Посмотреть сообщение
как заставить вот такую конструкцию завершать ввод при вводе '\n':
такую никак не заставишь.... зачем выпендрёж? проверяй ввод в цикле каком нибуть ...
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 11:05     Признак окончания потока для буферного итератора #7
Цитата Сообщение от Ilot Посмотреть сообщение
Если бы я мог привести пример кода то не задавал бы такой вопрос.
Цитата Сообщение от Ilot Посмотреть сообщение
как заставить вот такую конструкцию завершать ввод при вводе '\n':
Это разве не пример?
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
14.04.2014, 12:26  [ТС]     Признак окончания потока для буферного итератора #8
Цитата Сообщение от newbie666 Посмотреть сообщение
такую никак не заставишь.... зачем выпендрёж? проверяй ввод в цикле каком нибуть ...
Потребность в этой хрени весьма прозаическая. Зачастую форматированный ввод совсем не требуется. Например пользователь вводит определенное число и програме требуется пропарсить его разряды. Обычно в таком случае вводят переменную числового типа, а затем в цикле делят его на 10. Вопрос зачем это делать если пользователь изначально задает число ввиде последовательности символов, которые я могу загнать например в строку или вектор, а также в свой класс, но для этого мне необходим посимвольный парсинг вводимой строки. Вот такие дела.
Цитата Сообщение от newbie666 Посмотреть сообщение
такую никак не заставишь....
На самом то деле заставить легко об этом я писал выше. Проблема возникает при связывании входного/выходного потоков с консолью. Т.о. мы опять возвращаемся к тому вопросу который я не так давно задавал и не получил на него ответа...
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 12:50     Признак окончания потока для буферного итератора #9
Сообщение было отмечено автором темы, экспертом или модератором как ответ
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T>
void my_copy(std::istreambuf_iterator<char> in, T& Container)
{
    while (true)
    {
        Container.push_back(*in++);
        if ((cin.rdbuf() ->in_avail()) == 0)
            break;
    }
}
 
vector <char> Container;
std::istreambuf_iterator<char> in(std::cin);
my_copy(in, Container);
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
14.04.2014, 13:19  [ТС]     Признак окончания потока для буферного итератора #10
А говорила мне мамка учи потоки жаль не послушался. Надо бы это исправить...
alsav22, спасибо, но вот только в вектор заносится только один символ... Да и насколько мне позволяет буржуский in_avail() возвращает кол-во символов которые еще остались в потоке. А ведь '\n' тоже простой символ, а именно его мне нужно отслеживать. Отсюда вопрос: есть ли возможность посимвольно читать буфер?

Добавлено через 6 минут
Неужели я такой дурак?
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <fstream>
int main()
{
    std::vector<char> Container;
    std::istreambuf_iterator<char> bcin(std::cin);
    while(*bcin != '\n') {
        Container.push_back(*bcin++);
    }
    std::copy(Container.begin(), Container.end(), std::ostream_iterator<char>(std::cout, ""));
    std::cout << std::endl;
    return 0;
}
alsav22, благодарю, что навели на мысль.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 13:33     Признак окончания потока для буферного итератора #11
Цитата Сообщение от Ilot Посмотреть сообщение
спасибо, но вот только в вектор заносится только один символ..
Не пойму, о чём это?
Миниатюры
Признак окончания потока для буферного итератора  
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 13:35     Признак окончания потока для буферного итератора #12
Чтобы '\n' не попал в контейнер:
C++
1
2
if ((cin.rdbuf()->in_avail()) == 1)
            break;
Добавлено через 47 секунд
Цитата Сообщение от Ilot Посмотреть сообщение
Отсюда вопрос: есть ли возможность посимвольно читать буфер?
Он посимвольно и читается.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
14.04.2014, 13:57  [ТС]     Признак окончания потока для буферного итератора #13
Во!
Миниатюры
Признак окончания потока для буферного итератора  
DrOffset
6426 / 3800 / 880
Регистрация: 30.01.2014
Сообщений: 6,594
14.04.2014, 14:15     Признак окончания потока для буферного итератора #14
Цитата Сообщение от Ilot Посмотреть сообщение
который я не так давно задавал и не получил на него ответа...
Странно. Вроде бы ты получил ответ, причем даже не один раз
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 14:52     Признак окончания потока для буферного итератора #15
Цитата Сообщение от Ilot Посмотреть сообщение
Во!
Понял - это особенности mingw. Тогда добавить:
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
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
 
template <class T>
void my_copy(std::istreambuf_iterator<char> in, T& Container)
{
    while (true)
    {
        Container.push_back(*in++);
 
        if ((cin.rdbuf() ->in_avail()) == 1)
        break;
    }
}
 
int main()
{
    vector <char> Container;
 
    ios_base::sync_with_stdio(0); // !!!
    std::istreambuf_iterator<char> in(std::cin);
 
    my_copy(in, Container);
 
    for (int i = 0; i < Container.size(); ++i)
        cout << Container[i];
    cout << endl;
}
Миниатюры
Признак окончания потока для буферного итератора  
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
14.04.2014, 15:05  [ТС]     Признак окончания потока для буферного итератора #16
Цитата Сообщение от DrOffset Посмотреть сообщение
Странно. Вроде бы ты получил ответ, причем даже не один раз
Может быть. Однако таки не был получен ответ на вопрос как связать буфер с входным/выходным потоками консоли. И на самом деле только ваше последнее сообщение более мение соответствовало сути вопроса, предыдущие ответы не соответствовали самой постановке вопроса в плане использования пользовательского типа символом. А вот код в последнем посте к сожалению не связывает буфер с выходным потоком. Вот такие дела.

Добавлено через 2 минуты
alsav22, как я понял это синхронизация со стандартными потоками С. А можете поподробнее разъяснить в чем собственно тонкость?
DrOffset
6426 / 3800 / 880
Регистрация: 30.01.2014
Сообщений: 6,594
14.04.2014, 15:13     Признак окончания потока для буферного итератора #17
Цитата Сообщение от Ilot Посмотреть сообщение
А вот код в последнем посте к сожалению не связывает буфер с выходным потоком
Я предполагал, что ты сможешь это сделать самостоятельно. Нужно было только реализовать должным образом класс console_buffer. Именно он и связывает с консолью. Если это было не понятно из моего ответа, то стоило спросить
А по текущей теме можно предложить еще реализовать свой собственный итератор, который умеет собственный eof:
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
template <typename CharT, typename Traits = std::char_traits<CharT> >
class endline_iterator
    : public std::iterator<std::input_iterator_tag, CharT, typename Traits::off_type, CharT *, CharT &>
{
public:
    typedef CharT                                   char_type;
    typedef Traits                                  traits_type;
    typedef typename Traits::int_type               int_type;
    typedef std::basic_streambuf<CharT, Traits>     streambuf_type;
    typedef std::basic_istream<CharT, Traits>       istream_type;
 
private:
    mutable streambuf_type *  sbuf;
    mutable int_type          c;
 
public:
    endline_iterator() throw()
        : sbuf(0), c(eof_value())
    { }
 
    endline_iterator(istream_type & s) throw()
        : sbuf(s.rdbuf()), c(eof_value())
    { }
 
    endline_iterator(streambuf_type * s) throw()
        : sbuf(s), c(eof_value())
    { }
 
    char_type operator*() const
    {
        return traits_type::to_char_type(get());
    }
 
    endline_iterator & operator++()
    {
        if(sbuf)
        {
            sbuf->sbumpc();
            c = eof_value();
        }
        return *this;
    }
 
    endline_iterator operator++(int)
    {
        endline_iterator old = *this;
        if(sbuf)
        {
            old.c = sbuf->sbumpc();
            c = eof_value();
        }
        return old;
    }
 
    bool equal(endline_iterator const & b) const
    {
        return at_eof() == b.at_eof();
    }
 
private:
    static int_type eof_value() // eof - это конец строки
    {
        return int_type('\n');
    }
 
    int_type get() const
    {
        const int_type eof = eof_value();
        int_type ret = eof;
        if(sbuf)
        {
            if (!traits_type::eq_int_type(c, eof))
                ret = c;
            else if (!traits_type::eq_int_type((ret = sbuf->sgetc()), eof))
                c = ret;
            else
                sbuf = 0;
        }
        return ret;
    }
 
    bool at_eof() const
    {
        const int_type eof = eof_value();
        return traits_type::eq_int_type(get(), eof);
    }
};
 
template<typename CharT, typename Traits>
inline 
bool operator==(endline_iterator<CharT, Traits> const & a,
           endline_iterator<CharT, Traits> const & b)
{
    return a.equal(b);
}
 
template<typename CharT, typename Traits>
inline
bool operator!=(endline_iterator<CharT, Traits> const & a,
                endline_iterator<CharT, Traits> const & b)
{
    return !a.equal(b);
}
Добавлено через 4 минуты
Вызов соответственно будет такой:
C++
1
std::copy(endline_iterator<char>(std::cin), endline_iterator<char>(), std::back_inserter(Container));
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
14.04.2014, 15:16  [ТС]     Признак окончания потока для буферного итератора #18
Цитата Сообщение от DrOffset Посмотреть сообщение
Я предполагал, что ты сможешь это сделать самостоятельно. Нужно было только реализовать должным образом класс console_buffer. Именно он и связывает с консолью.
Вот именно в этом и состоял вопрос. Если бы я знал как это сделать то, по-видимому, не создавал бы тему.
Цитата Сообщение от DrOffset Посмотреть сообщение
А по текущей теме можно предложить еще реализовать свой собственный итератор, который умеет собственный eof:
Не думаю, что стоит так усложнять задачу ради одного метода. К тому же более простое решение указанно в одном из моих последних сообщений, но все равно спасибо.
Вообще-то достаточно просто перегрузить констукторы.
DrOffset
6426 / 3800 / 880
Регистрация: 30.01.2014
Сообщений: 6,594
14.04.2014, 15:21     Признак окончания потока для буферного итератора #19
Цитата Сообщение от Ilot Посмотреть сообщение
Не думаю, что стоит так усложнять задачу ради одного метода.
Это зависит от ситуации. Допустим здесь и не стоит, в целях самообразования разве что

Добавлено через 55 секунд
Цитата Сообщение от Ilot Посмотреть сообщение
Вот именно в этом и состоял вопрос. Если бы я знал как это сделать то, по-видимому, не создавал бы тему.
Если интересно, то вечером могу показать пример.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.04.2014, 15:26     Признак окончания потока для буферного итератора
Еще ссылки по теме:

С клавиатуры вводятся последовательность целых чисел 0 - признак окончания последовательности C++
Составить программу для нахождения времени окончания просмотра фильма C++
Бинарные файлы. Признак окончания файла C++

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

Или воспользуйтесь поиском по форуму:
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 15:26     Признак окончания потока для буферного итератора #20
Цитата Сообщение от Ilot Посмотреть сообщение
как я понял это синхронизация со стандартными потоками С. А можете поподробнее разъяснить в чем собственно тонкость?
Без понятия, просто на практике столкнулся (в студии всё работает и так). Это, скорее, вопрос к знатокам gcc и Linux (так как именно там без этого не работает).
Yandex
Объявления
14.04.2014, 15:26     Признак окончания потока для буферного итератора
Ответ Создать тему
Опции темы

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