Что такое поток в с
Перейти к содержимому

Что такое поток в с

  • автор:

Что такое поток

Как и В, C++ не имеет встроенных возможностей ввода и вывода. Однако все компиляторы C++ объединяются с системным, объектно-ориентированным пакетом ввода-вывода, известным как iostream классы. Поток является центральным понятием iostream классов. Можно считать, что поток — это смарт-файл, который выступает в качестве источника и назначения для байт. Характеристики потока определяется его классом и пользовательскими операторами вставки и извлечения.

С помощью драйверов устройств дисковая операционная система взаимодействует с клавиатурой, монитором, принтером и портами ввода-вывода как с расширенными файлами. Классы iostream взаимодействуют с этими расширенными файлами. Встроенные классы поддерживают чтение из памяти и запись в память, причем синтаксис этих операций идентичен синтаксису для операций дискового ввода-вывода, что позволяет легко создавать производные классы потока.

В этом разделе

См. также

Дополнительные ресурсы

Значок отказа согласно Закону Калифорнии о защите конфиденциальности потребителей (CCPA)

  • Светлая
  • Темная
  • Высокая контрастность
  • Предыдущие версии
  • Блог
  • Участие в доработке
  • Конфиденциальность
  • Условия использования
  • Товарные знаки
  • © Microsoft 2024

Дополнительные ресурсы

Значок отказа согласно Закону Калифорнии о защите конфиденциальности потребителей (CCPA)

  • Светлая
  • Темная
  • Высокая контрастность
  • Предыдущие версии
  • Блог
  • Участие в доработке
  • Конфиденциальность
  • Условия использования
  • Товарные знаки
  • © Microsoft 2024

Что такое поток (stream)?

В книжках пишут про стандартные потоки ввода-вывода в C++, запись в поток и чтение из потока. Что такое поток, и что он из себя представляет?

Отслеживать
31k 13 13 золотых знаков 96 96 серебряных знаков 157 157 бронзовых знаков
задан 14 июл 2015 в 15:29
357 1 1 золотой знак 2 2 серебряных знака 8 8 бронзовых знаков

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Поток это просто абстракция. Удобная абстракция для решения задач.

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

Рассмотрим например, такое чтение с консоли:

int n; std::string s; std::cin >> n >> s; 

и такие данные на вход:

123a aaa 

Как это будет работать? Вначале стандартному потоку нужно прочитать число. Он будет читать до тех пор, пока там число. В n попадет 123. В «трубе осталось «a aaa». Дальше нужно прочитать строку. А строка читается до пробела или перевода строки. Поэтому прочитается только одно a. А многие полагают, что прочитается три а. Я привел этот пример не просто так. На него многие попадаются.

Как это реализовано внутри? Очень просто. Есть очередь (то есть, если очень грубо — массив), откуда читают данные байт за байтом. Если в очереди ничего нет — библиотечный код обращается к функциям операционной системы и читает с консоли/файла/сокета) и складывает в очередь. Конечно, в некоторых случаях эта очередь может быть реализована на базе операционной системы, а может и явно. Но для пользователя (то есть программиста) это прозрачно.

Аналогично работает и вывод.

Чем удобны потоки?

После того, как поток «подключен» к файлу или консоли, дальше все идет одинаково. Можно, к примеру написать функции, которые будут выводить в поток, но при этом абсолютно не знать, куда именно они выводят. Это позволяет писать обобщенные алгоритмы и прочие вкусности.

Например, нужно сделать функцию форматированного вывода числа на консоль (со спец. пожеланиями). Можно конечно закодить вывод на std::cout, но как протестить? Можно написать функцию, которая будет на вход получать ostream (предок std::cout) и выводить в него. Потом можно использовать такую функцию и выводить в stringstream, который легко преобразовывается в строку и результат можно выверить тестом.

Потоки

Система ввода/вывода С предназначена для работы со множеством устройств, включая терминалы дисковые накопители и так далее. Хотя каждое устройство отличается от другого, система вводу вывода преобразует их в единое логическое устройство — поток. Все потоки похожи своим поведением. Поскольку потоки не зависят от устройств, одни и те же функции могут записывать информацию в файл на диске и использоваться для записи на другое устройство, например консоль. Существует два типа потоков: текстовые и двоичные.

Текстовые потоки

Текстовые потоки — это последовательность символов. В текстовых потоках некоторые символы могут преобразовываться согласно требованиям среды. Например, символ новой строки может преобразовываться в пару «возврат каретки — перевод строки». Следовательно, может не быть однозначного соответствия между записываемыми или считываемыми символами и символами во внешнем устройстве. Также из-за возможного перевода число символов, прочитанных или записанных, может не совпадать с числом символов во внешнем устройстве.

Двоичные потоки

Двоичный поток — это последовательность байт, имеющих однозначное соответствие с байтами во внешнем устройстве. То есть, не возникает преобразование символов. Также число байт, записанных или прочитанных из внешнего устройства, совпадает с числом во внешнем устройстве. Тем не менее может добавляться некоторое количество нулевых байт к двоичному потоку. Эти нулевые байты могут использоваться для унификации представления информации, например для заполнения сектора диска.

Урок №207. Потоки ввода и вывода

Функционал потоков ввода/вывода не определен как часть языка C++, а предоставляется Стандартной библиотекой C++ (и, следовательно, находится в пространстве имен std). На предыдущих уроках мы подключали заголовочный файл библиотеки iostream и использовали объекты cin и cout для простого ввода/вывода данных. На этом уроке мы детально рассмотрим библиотеку iostream.

Оглавление:

  1. Библиотека iostream
  2. Потоки в C++
  3. Ввод/вывод в C++
  4. Стандартные потоки в C++
  5. Пример на практике

Библиотека iostream

При подключении заголовочного файла iostream, мы получаем доступ ко всей иерархии классов библиотеки iostream, отвечающих за функционал ввода/вывода данных (включая класс, который называется iostream). Иерархия этих классов выглядит примерно следующим образом:

Первое, что вы можете заметить в этой иерархии — множественное наследование (то, что на самом деле не рекомендуется использовать). Тем не менее, библиотека iostream была разработана и тщательно протестирована соответствующим образом, дабы избежать типичных ошибок, которые возникают при работе с множественным наследованием, поэтому вы можете спокойно использовать эту библиотеку.

Потоки в С++

Второе, что вы могли бы заметить — это частое использование слова «stream» (т.е. «поток»). По сути, ввод/вывод в языке C++ реализован с помощью потоков. Абстрактно, поток — это последовательность символов, к которым можно получить доступ. Со временем поток может производить или потреблять потенциально неограниченные объемы данных.

Мы будем иметь дело с двумя типами потоков. Поток ввода (или «входной поток») используется для хранения данных, полученных от источника данных: клавиатуры, файла, сети и т.д. Например, пользователь может нажать клавишу на клавиатуре в то время, когда программа не ожидает ввода. Вместо игнорирования нажатия клавиши, данные помещаются во входной поток, где затем ожидают ответа от программы.

И наоборот, поток вывода (или «выходной поток») используется для хранения данных, предоставляемых конкретному потребителю данных: монитору, файлу, принтеру и т.д. При записи данных на устройство вывода, это устройство может быть не готовым принять данные немедленно. Например, принтер все еще может прогреваться, когда программа уже записывает данные в выходной поток. Таким образом, данные будут находиться в потоке вывода до тех пор, пока принтер не начнет их использовать.

Некоторые устройства, такие как файлы и сети, могут быть источниками как ввода, так и вывода данных.

Хорошая новость заключается в том, что программисту не нужно знать детали взаимодействия потоков с разными устройствами и источниками данных, ему нужно только научиться взаимодействовать с этими потоками для чтения и записи данных.

Ввод/вывод в C++

Хотя класс ios является дочерним классу ios_base , очень часто именно этот класс будет наиболее родительским классом, с которым вы будете работать/взаимодействовать напрямую. Класс ios определяет кучу разных вещей, которые являются общими для потоков ввода/вывода.

Класс istream используется для работы с входными потоками. Оператор извлечения >> используется для извлечения значений из потока. Это имеет смысл: когда пользователь нажимает на клавишу клавиатуры, код этой клавиши помещается во входной поток. Затем программа извлекает это значение из потока и использует его.

Класс iostream может обрабатывать как ввод, так и вывод данных, что позволяет ему осуществлять двунаправленный ввод/вывод.

Наконец, остались 3 класса, оканчивающиеся на _withassign . Эти потоковые классы являются дочерними классам istream , ostream и iostream (соответственно). В большинстве случаев вы не будете работать с ними напрямую.

Стандартные потоки в C++

Стандартный поток — это предварительно подключенный поток, который предоставляется программе её окружением. Язык C++ поставляется с 4-мя предварительно определенными стандартными объектами потоков, которые вы можете использовать (первые три вы уже встречали):

cin — класс istream_withassign , связанный со стандартным вводом (обычно это клавиатура);

cout — класс ostream_withassign , связанный со стандартным выводом (обычно это монитор);

cerr — класс ostream_withassign , связанный со стандартной ошибкой (обычно это монитор), обеспечивающий небуферизованный вывод;

clog — класс ostream_withassign , связанный со стандартной ошибкой (обычно это монитор), обеспечивающий буферизованный вывод.

Небуферизованный вывод обычно обрабатывается сразу же, тогда как буферизованный вывод обычно сохраняется и выводится как блок. Поскольку clog используется редко, то его обычно игнорируют.

Пример на практике

Вот пример использования ввода/вывода данных со стандартными потоками:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *