Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
1

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

11.04.2014, 13:44. Показов 2093. Ответов 25
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Собственно надоело вводить 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 минут
Неужели задача такая сложная?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.04.2014, 13:44
Ответы с готовыми решениями:

Не работает признак окончания ввода(признак-0)
Признак окончания ввода 0; подскажите люди добрые что не так?) #include <iostream>...

Можно ли задать ограничения для итератора потока ввода?
Изучая c++, наткнулся на такой способ заполнения вектора из потока. istream_iterator< int >...

Бинарные файлы. Признак окончания файла
Здравствуйте Возникла проблема при чтении с бинарного файла, программа не может найти конец файла...

С клавиатуры вводятся последовательность целых чисел.0 - признак окончания последовательности
С клавиатуры вводятся последовательность целых чисел.0 - признак окончания...

25
Tulosba
11.04.2014, 14:44
  #2

Не по теме:

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

0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
11.04.2014, 15:02  [ТС] 3
Tulosba, ну очень смешно.
Пытался написать свой тип от char_traits, но вовремя понял, что ни к чему хорошему это не приведет.
EOF запрятан где-то очень глубоко в заголовочниках и как на него повлиять неизвестно.
Есть ли другой путь?
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.04.2014, 16:02 4
Цитата Сообщение от Ilot Посмотреть сообщение
Есть ли другой путь?
Для чего? Чтобы не вводить ctrl+z для ввода признака окончания потока? Пример кода приведите.
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
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));
0
Заблокирован
14.04.2014, 09:20 6
Цитата Сообщение от Ilot Посмотреть сообщение
как заставить вот такую конструкцию завершать ввод при вводе '\n':
такую никак не заставишь.... зачем выпендрёж? проверяй ввод в цикле каком нибуть ...
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 11:05 7
Цитата Сообщение от Ilot Посмотреть сообщение
Если бы я мог привести пример кода то не задавал бы такой вопрос.
Цитата Сообщение от Ilot Посмотреть сообщение
как заставить вот такую конструкцию завершать ввод при вводе '\n':
Это разве не пример?
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
14.04.2014, 12:26  [ТС] 8
Цитата Сообщение от newbie666 Посмотреть сообщение
такую никак не заставишь.... зачем выпендрёж? проверяй ввод в цикле каком нибуть ...
Потребность в этой хрени весьма прозаическая. Зачастую форматированный ввод совсем не требуется. Например пользователь вводит определенное число и програме требуется пропарсить его разряды. Обычно в таком случае вводят переменную числового типа, а затем в цикле делят его на 10. Вопрос зачем это делать если пользователь изначально задает число ввиде последовательности символов, которые я могу загнать например в строку или вектор, а также в свой класс, но для этого мне необходим посимвольный парсинг вводимой строки. Вот такие дела.
Цитата Сообщение от newbie666 Посмотреть сообщение
такую никак не заставишь....
На самом то деле заставить легко об этом я писал выше. Проблема возникает при связывании входного/выходного потоков с консолью. Т.о. мы опять возвращаемся к тому вопросу который я не так давно задавал и не получил на него ответа...
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 12:50 9
Лучший ответ Сообщение было отмечено Ilot как решение

Решение

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);
1
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
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, благодарю, что навели на мысль.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 13:33 11
Цитата Сообщение от Ilot Посмотреть сообщение
спасибо, но вот только в вектор заносится только один символ..
Не пойму, о чём это?
Миниатюры
Признак окончания потока для буферного итератора  
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 13:35 12
Чтобы '\n' не попал в контейнер:
C++
1
2
if ((cin.rdbuf()->in_avail()) == 1)
            break;
Добавлено через 47 секунд
Цитата Сообщение от Ilot Посмотреть сообщение
Отсюда вопрос: есть ли возможность посимвольно читать буфер?
Он посимвольно и читается.
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
14.04.2014, 13:57  [ТС] 13
Во!
Миниатюры
Признак окончания потока для буферного итератора  
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
14.04.2014, 14:15 14
Цитата Сообщение от Ilot Посмотреть сообщение
который я не так давно задавал и не получил на него ответа...
Странно. Вроде бы ты получил ответ, причем даже не один раз
0
5498 / 4893 / 831
Регистрация: 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;
}
Миниатюры
Признак окончания потока для буферного итератора  
1
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
14.04.2014, 15:05  [ТС] 16
Цитата Сообщение от DrOffset Посмотреть сообщение
Странно. Вроде бы ты получил ответ, причем даже не один раз
Может быть. Однако таки не был получен ответ на вопрос как связать буфер с входным/выходным потоками консоли. И на самом деле только ваше последнее сообщение более мение соответствовало сути вопроса, предыдущие ответы не соответствовали самой постановке вопроса в плане использования пользовательского типа символом. А вот код в последнем посте к сожалению не связывает буфер с выходным потоком. Вот такие дела.

Добавлено через 2 минуты
alsav22, как я понял это синхронизация со стандартными потоками С. А можете поподробнее разъяснить в чем собственно тонкость?
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
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));
2
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
14.04.2014, 15:16  [ТС] 18
Цитата Сообщение от DrOffset Посмотреть сообщение
Я предполагал, что ты сможешь это сделать самостоятельно. Нужно было только реализовать должным образом класс console_buffer. Именно он и связывает с консолью.
Вот именно в этом и состоял вопрос. Если бы я знал как это сделать то, по-видимому, не создавал бы тему.
Цитата Сообщение от DrOffset Посмотреть сообщение
А по текущей теме можно предложить еще реализовать свой собственный итератор, который умеет собственный eof:
Не думаю, что стоит так усложнять задачу ради одного метода. К тому же более простое решение указанно в одном из моих последних сообщений, но все равно спасибо.
Вообще-то достаточно просто перегрузить констукторы.
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
14.04.2014, 15:21 19
Цитата Сообщение от Ilot Посмотреть сообщение
Не думаю, что стоит так усложнять задачу ради одного метода.
Это зависит от ситуации. Допустим здесь и не стоит, в целях самообразования разве что

Добавлено через 55 секунд
Цитата Сообщение от Ilot Посмотреть сообщение
Вот именно в этом и состоял вопрос. Если бы я знал как это сделать то, по-видимому, не создавал бы тему.
Если интересно, то вечером могу показать пример.
1
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
14.04.2014, 15:26 20
Цитата Сообщение от Ilot Посмотреть сообщение
как я понял это синхронизация со стандартными потоками С. А можете поподробнее разъяснить в чем собственно тонкость?
Без понятия, просто на практике столкнулся (в студии всё работает и так). Это, скорее, вопрос к знатокам gcc и Linux (так как именно там без этого не работает).
1
14.04.2014, 15:26
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.04.2014, 15:26
Помогаю со студенческими работами здесь

С клавиатуры вводятся последовательность целых чисел 0 - признак окончания последовательности
определит ьверно ли утверждение количество нечетных чисел последовательности меньше количества...

Прочитать строку с клавиатуры (признак окончания строки – нажатие Enter)
Прочитать строку с клавиатуры (признак окончания строки – нажатие Enter) и добавить его в другой,...

Пользователь вводит любые числа с клааиатуры,признак окончания 0. Проверить если в данной последовательности 5
Пользователь вводит любые числа с клавиатуры признак окончания 0, Проверить,если в данной...

Ввод пользователем заранее НЕ известного количества чисел(выбрать признак окончания ввода-число 999)
Ввод пользователя заранее НЕ известного количества чисел(выбрать признак окончания ввода-число 999)...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru