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

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

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

Один из основных механизмов, который делает программу полезной является ввод/вывод. Все языки программирования имеют такой механизм. Среди операторов и ключевых слов нет ввода/вывода. Потому что в языке С++ ввод/вывод реализован в виде библиотеки. И вообще многие механизмы, которые делают язык С++ таким мощным реализованы в библиотеках (стандартные, специализированные, персональные).

В С++ используется механизм потокового ввода/вывода. Поток — механизм преобразования значений различного типа в последовательность символов (вывод) и наоборот (ввод), в значение переменной.

Вывод: Помещение (направление) данных в поток вывода осуществляется с помощью оператора << который также иногда называют экстрактор (extractor). Конечно, можно создать свой поток вывода, но обычно достаточно стандартных потоков:

  • cout — стандартный поток вывода (экран)
  • cerr — стандартный поток вывода ошибок (экран)

Переменную любого встроенного типа можно вывести используя следующую запись:

cout<<«x Data types:»<<endl; // вывод строки
cout<<«int float double navigate.html» > ‘
flush; // очистка буфера потока

Это лишь основные манипуляторы, которые вы можете использовать для форматирования. С остальными познакомьтесь самостоятельно:

Манипулятор Действие на поток
showbase
noshowbase
инициирует отображение основания системы счисления
showpos
noshowpos
инициирует явное отображение знака (+) для положительных значений
uppercase
nouppercase
инициирует преобразование выводимых символов в верхний регистр
showpoint
noshowpoint
инициирует отображение десятичной точки при выводе вещественных чисел
skipws
noskipws
инициирует пропуск пробельных символов при вводе
left инициирует левое выравнивание, заполнение справа
right инициирует правое выравнивание, заполнение слева
internal инициирует внутреннее заполнение (между значением и знаком или основанием системы счисления)
scientific инициирует вывод вещественных значений в научном формате (d.ddddddddE+dd)
fixed инициирует вывод вещественных значений в фиксированном формате (d.dddddd)
setbase (int base) изменяет систему счисления (10, 8, 16)
dec инициирует вывод целочисленных значений в десятичной системе счисления
oct инициирует вывод целочисленных значений в восьмеричной системе счисления
hex инициирует вывод целочисленных значений в шестнадцатеричной системе счисления
setfill (char n) задает заполняющий символ
setprecision (int n) изменяет точность выводимых значений
setw (int n) задает ширину поля вывода

Файловые потоки

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

void main()
<
ifstream inputfile(«z:\data.txt»); // создается поток ввода из файла
inputfile>>x; // все то же самое что и для cin
ofstream outputfile(«z:\res.txt»); // создается поток вывода в файл
outputfile<<x; // все то же самое что и для cout
>

Обратите внимание на двойной слэш \ в имени файла. Это все из-за того, что \ — экранирующий символ.

По умолчанию ввод и вывод данных в поток осуществляется в текстовом режиме. Для того, чтобы данные выводились в двоичном режиме следует использовать следующую запись:

По умолчанию файл открываемый для вывода создается (если он создан), а если существует, то очищается. Для того чтобы открыть файл для добавления:

Многопоточность

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

Основной функционал для использования потоков в приложении сосредоточен в пространстве имен System.Threading . В нем определен класс, представляющий отдельный поток — класс Thread .

Класс Thread определяет ряд методов и свойств, которые позволяют управлять потоком и получать информацию о нем. Основные свойства класса:

ExecutionContext : позволяет получить контекст, в котором выполняется поток

IsAlive : указывает, работает ли поток в текущий момент

IsBackground : указывает, является ли поток фоновым

Name : содержит имя потока

ManagedThreadId : возвращает числовой идентификатор текущего потока

Priority : хранит приоритет потока — значение перечисления ThreadPriority :

По умолчанию потоку задается значение Normal. Однако мы можем изменить приоритет в процессе работы программы. Например, повысить важность потока, установив приоритет Highest. Среда CLR будет считывать и анализировать значения приоритета и на их основании выделять данному потоку то или иное количество времени.

ThreadState возвращает состояние потока — одно из значений перечисления ThreadState :

Aborted : поток остановлен, но пока еще окончательно не завершен

AbortRequested : для потока вызван метод Abort, но остановка потока еще не произошла

Background : поток выполняется в фоновом режиме

Running : поток запущен и работает (не приостановлен)

Stopped : поток завершен

StopRequested : поток получил запрос на остановку

Suspended : поток приостановлен

SuspendRequested : поток получил запрос на приостановку

Unstarted : поток еще не был запущен

WaitSleepJoin : поток заблокирован в результате действия методов Sleep или Join

В процессе работы потока его статус многократно может измениться под действием методов. Так, в самом начале еще до применения метода Start его статус имеет значение Unstarted . Запустив поток, мы изменим его статус на Running . Вызвав метод Sleep, статус изменится на WaitSleepJoin .

Кроме того статическое свойство CurrentThread класса Thread позволяет получить текущий поток

В программе на C# есть как минимум один поток — главный поток, в котором выполняется метод Main.

Например, используем вышеописанные свойства для получения информации о потоке:

В этом случае мы получим примерно следующий вывод:

Так как по умолчанию свойство Name у объектов Thread не установлено, то в первом случае мы получаем в качестве значения этого свойства пустую строку.

Также класс Thread определяет ряд методов для управления потоком. Основные из них:

Статический метод GetDomain возвращает ссылку на домен приложения

Статический метод GetDomainID возвращает id домена приложения, в котором выполняется текущий поток

Статический метод Sleep останавливает поток на определенное количество миллисекунд

Метод Interrupt прерывает поток, который находится в состоянии WaitSleepJoin

Метод Join блокирует выполнение вызвавшего его потока до тех пор, пока не завершится поток, для которого был вызван данный метод

Метод Start запускает поток

Например, применим метод Sleep для задания задержки выполнения приложения:

Лекция 7. Потоки ввода/вывода

Чтение данных из потока называется извлечением, а запись в поток- помещением.

Иерархия потоков

Потоки ввода/вывода

В языке С++ с каждым устройством ассоциируется поток ввода/вывода:

  • cin — стандартный поток ввода (клавиатура)
  • cout — стандартный поток вывода (терминал)
  • cerr — стандартный поток ошибок.

При работе с потоками происходит автоматический перевод из типа данных в строку для вывода на экран и из строки в числовой тип при вводе.

Для работы со стандартными потоками подключается заголовочный файл iostream

Потоки ввода вывода

Данные разных типов можно смешивать:

Ввод/вывод строк

При вводе строк извлечение происходит до ближайшего пробела (или другого стандартного разделителя)

Для ввода строк целиком используются методы потоков get и getline.

В следующем примере демонстрируется ввод строк целиком

Ввод вывод строк

Для обеспечения безопасного ввода может применяться манипулятор setw:

Циклический ввод-вывод

Данный цикл позволяет ввести строку, а потом очищает ее от разделителей при выводе.

Циклическии ввод-вывод

Здесь осуществляется посимвольный ввод/вывод вместе с разделителями

Форматирование

С помощью механизма флагов можно управлять параметрами вывода данных на консоль.

Устанавливается значение флага через метод setf, а снимается с помощью unsetf.

Вывод логических величин в текстовом виде:

Основные флаги форматирования:

  • left — левое выравнивание
  • right — правое выравнивание
  • boolalpha — вывод логических значений в текстовом виде
  • dec — основание системы счисления 10
  • oct — основание системы счисления 8
  • hex — основание системы счисления 16
  • showbase — выводить индикатор системы счисления
  • showpos — показывать + для положительных чисел
  • scientific — экспонециальная форма вещественного числа
  • fixed — фиксированная форма вещественного числа

Помимо флагов, изменяющих состояние потока можно использовать манипуляторы.

Идея манипуляторов состоит в том, что их можно помещать в поток вместе с данными.

Многие манипуляторы повторяют названиями флаги.

Для работы с манипуляторами нужно подключить заголовочный файл iomanip.

  • setw() — установить ширину поля
  • setprecision() — количество цифр в дробной части
  • left — выравнивание по левой границе
  • right — выравнивание по правой границе
  • boolalpha — вывод логических значений в текстовом виде
  • nobool alpha — вывод логических значений в числовом виде
  • dec — десятичная система счисления
  • oct — восьмеричная система счисления
  • hex — шестнадцатиричная система счисления
  • showbase — показывать признак системы счисления
  • noshowbase — не показывать признак системы счисления
  • showpos — выводить + для положительных чисел
  • noshowpos — не выводить + для положительных чисел
  • sceintific — экспоненциальная форма для вещественных чисел
  • fixed — фиксированная форма
  • setfill() — установить символ заполнитель пустых элементов поля

2 Файловые потоки

Файлы данных

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

Файлы данных используются для хранения информации в перерывах между сеансами работы пользователей.

Для работы с файлами данных в С++ используются специальные файловые потоки

Порядок работы с файлом

При работе с файлом придерживаются следующей последовательности:

  1. Открытие файла (создание потокового объекта).
  2. Проверка результата открытия.
  3. Чтение/запись данных.
  4. Закрытие файла.

Иногда после открытия требуется позиционирование, то есть перемещение к нужной позиции внутри открытого файла.

Открытие файла

Для работы с файлами мы подключаем заголовочный файл fstream

Заголовочный файл определяет несколько потоков для работы с файлами

  • ifstream — для чтения данных из файла
  • ofstream — для записи данных в файл
  • fstream — для записи и чтения данных

В следующем примере файл 1.txt открывается для чтения, а 2.txt — для записи:

Открывать файлы можно другим способом.

Сначала создаются объекты файловых потоков, а затем вызывается метод open() файлового потока:

У данного способа есть два преимущества:

  • Можно снова открыть тот же самый файл после закрытия не создавая новый потоковый объект.
  • Один и тот же потоковый объект может применяться для открытия нескольких файлов (последовательно).

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

Относительное имя

Короткое имя файла в текущем каталоге

Абсолютное (полное) имя

Путевое имя файла в операционной системе

Пример с использованием полного имени в ОС Windows:

Следует обратить внимание на то, что обратный слэш в строковых константах должен удваиваться.

Пример с использованием полного имени в ОС Unix:

У файловых объектов есть функция fail(), которая в случае ошибки открытия возвращает истинное значение.

При открытии на чтение, входной файл должен существовать.

При открытии на запись, файлу существовать необязательно, поскольку он все равно будет создан.

Закрытие файла

Для закрытия файла используется функция close().

При закрытии файла, в который производилась запись, все данные будут записаны на диск.

Чтение данных

Чтение данных из файла может осуществляться разными способами:

  • посимвольно (побайтно);
  • поэлементно (до пробела или перевода строки);
  • построчно;
  • поблочно.
Посимвольное чтение

В следующем примере файл читается посимвольно.

Построчное чтение

В следующем примере файл читается построчно.

Еще один пример функции, читающей файл построчно:

Поэлементное чтение

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

Поблочное чтение

Поблочное чтение означает, что из файла читается блок данных определенного размера.

В следующем примере мы читаем из файла структуру BOOK:

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

Запись в файлы

Операциям чтения данных из файла соответствуют операции записи данных.

Операции get соответствует put, операции readwrite.

В следующем примере показано использование операции помещения информации в поток:

В файл 2.txt помещается 10 строк с приветствием и его порядковым номером. При выводе в файл числовых значений они будут преобразованы в строки.

Запись и чтение

Файл можно открыть для записи и чтения:

С каждой операцией записи/чтения позиция внутри файла сдвигается на определенное число байт, равное размеру записанных или прочитанных данных. Для изменения текущей позиции надо использовать метод seekp().

Возможные варианты второго параметра seekp()

  1. pos::beg — начало файла
  2. pos::end — конец файла
  3. pos::cur — текущая позиция (любая)
Бинарный и текстовый режимы

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

В текстовом режиме при вводе/выводе символа перевода строки автоматически удаляется/добавляется символ возврата каретки.

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

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