Добавлен: 26.05.2023
Просмотров: 272
Скачиваний: 2
Введение
Темой данной курсовой работы является «Способы ввода/вывода в С++». Данная тема касается различных способов ввода данных и их вывода в программу, без которых работа этой программы невозможна. Целью курсовой работы является выяснение функций и области применения различных способов ввода/вывода информации в С++.
Любой программе и приложению для работы необходимы донные которые поставляются устройствами и методами ввода/вывода. Эти методы позволяют программе и пользователю (или двум программам) передавать друг другу необходимые данные. Например внешними устройствами ввода/вывода считаются клавиатура, мышь, монитор и т.д.
Но также есть программы, не использующие файловый или консольный ввод-вывод: обычно это программы работающие на низком уровне с аппаратной частью компьютера и его периферийными устройствами (ядро,мат.плата,дравйверы и т.д.)
В стандартной версии C++ существует 2 основных пути ввода-вывода информации:
- С использованием обычного способа ввода-вывода доставшегося от языка С
- с помощью потоков, реализованных в STL (Standard Template Library).
Однако оба этих способа, ввода-вывода для осуществления необходимых действий используют вызовы ОС.
1. Ввод и вывод в языке С
Для того чтобы приступить к описанию ввода-вывода в С++, сперва обратим взор на его «предка» от которого ему и достались большинство функций и методов.
Ввод-вывод в обычном языке С производится с использованием команд и функций из различных библиотек. Для того чтобы их использовать, в программе необходимо подключить необходимые h-файлы: stdio.h, stdlib.h, conio.h и др. Основная библиотека - stdio.h, в ней содержатся стандартные и самые широко используемые команды и функции.[1]
1.1 Ввод/вывод в работе с файлами
Для начала работы с различными видами файлов и данных в них, их надо связать со специализированной структурой с именем FILE, информация о которой находится в библиотеке stdio.h также в ней задаются некоторые свойства файла(размер буфера ввода/вывода, состояние файла, последняя прочитанная запись и т. п.).[2] Эта связь создается при использовании команды fopen(), которая также находится в библиотеке stdio.h, также она возвращает указатель на структуру FILE. Поэтому, прежде всего в программе, необходимо установить указатель на структуру FILE, а потом уже писать команду необходимую для открытия нужного файла:
FILE *fp;
fp = fopen(<точное имя файла>, <режим работы с файлом> ); [3]
В команде fopen() есть две настройки: точное имя файла и режим работы с файлом. В строке режима работы указывается какие действия пользователь хочет делать с файлом: только прочесть его, записать, или и то и другое.[4] Существуют следующие обозначения параметров открытия файла:
- r – позволяет только считывать данные с файла;
- w – этот параметр может использоваться только для записи данных в файл, если указывается имя несуществующего файла то он создается и открывается автоматически.
- a – нужен для добавления данных в конце файла, также при использовании имени несуществующего файла он создается и открывается автоматически.
- r+ – открывает существующий файл и позволяет читать и записывать в нем данные;
- w+ – создается новый файл для обновления: можно и читать, и записывать в него данные;
- a+ – используется для добавления данных в конец файла, если файл с указанным именем отсутствует то он создается автоматически. [5]
Бывает что файл не получается открыть из-за некоторых причин (например, в свойстве r+ написано имя несуществующего файла), тогда функция fopen() выставляет значение NULL. [6]Чтобы это предотвратить нужно выполнить проверку:
if((fp = fopen(name, mode)) == NULL)
[ операторы обработки ошибки открытия ]
[ остальные операторы программы ]
[7]После окончания работы с нужным файлом, необходимо отключить от него функцию FILЕ. Это делается с помощью функции fclose(fp). Эта функция используется не только для разрыва с функцией FILE, но и записывает в память оставшееся содержимое буфера ввода/вывода, через который и организуется ввод/вывод. Только после отвязывания файла от FILE он становится доступен для дальнейших команд. Например, его можно удалить или опять открыть в другом режиме работы и т.д.
Приведем фрагмент программы, в которой используется функция fopen() для открытия файла под именем TEST.
FILE *fp;
fp = fopen("test", "w");
Можно заметить недостаточность такого кода в программе. Хотя приведенный код технически правильный, но его обычно пишут немного по-другому.
FILE *fp;
if ((fp = fopen("test", "w")==NUL)
{
printf("Ошибка при открытии файла.\n\r")"
exit(1);
}[8]
Рис. 1 Пример кода
Таким способом можно найти ошибки которые мешают открытию файла. [9]
Допустим ошибку защиты или записи на жесткий диск. Причем, обнаружить еще до того, как программа попытается в этот файл что-то записать. Поэтому всегда нужно вначале получить подтверждение, что функция fopen() выполнилась успешно, и лишь затем выполнять c файлом другие операции. Выше на Рис.1 приведена небольшаю часть кода программы, в которой подтверждается или нет открытие файла. Результат проверки показан на Рис.2 ниже. [10]
Рис. 2. Результат проверки
В отсутствие ошибок файл открывается. [12]После того как файл открыт, то для чтения или записи данных используют специальные функции. Они распространяются библиотеками в которые вложены множества функций упрощающих работы с файлами и увеличивающие количество возможных используемых функций при работе с ними.[13]
- Функция fputc()
Вид функции: fputc(c, fp);
Функция выводит символ в файл: с – выводимый символ, fp – указатель на файл.
- Функция fputs()
Вид функции: fputs(s, fp);
Функция добавляет строку в файл: s – выводимая строка, fp – указатель на файл.
- Функция fgetc()
Вид функции: char c = fgetc(fp);
Считывает символ из файла с указателем fp. В случае ошибки или достижения конца файла возвращает EOF.
- Функция fgets()
Вид функции: fgets(s, maxline, fp);
Считывает строку кода из s, где s – массив символов или указатель типа char (предварительно должна быть выделена память для чтения с использованием указа- теля), maxline – указывает максимальное количество символов, которое требуется читать из файла с указателем fp. В случае ошибки или достижения конца файла возвращает NULL.
- Функция fread()
Вид функции: fread(buf, m, n, fp);
Эта функция считывает из файла c указателем fp первые n элементов данных, каждый из которых имеет длину m байт. Чтение происходит в буфер, на который указывает указатель buf, например, char buf[50] или char *buf (но в последнем случае предварительно надо выделить память для буфера). Общее количество байт чтения составит (n*m). Функция возвращает количество прочитанных элементов, а по достижении конца файла или возникновении ошибки чтения возвращает NULL.
- Функция fwrite()
Вид функции: fwrite(ptr, m, n, fp);
Данная функция добавляет n элементов в файл с указателем fp, каждый элемент длиной в m байт. Данные записываются из буфера, на который указывает указатель ptr (этот указатель указывает на некоторый объект, например, на структуру). Общее количество записанных байтов равно (n * m). В случае ошибки записи функция возвращает ноль, в противном случае — количество записанных элементов.[14]
- Функция fseek()
Вид функции: fseek(fp, n, m);
Данная функция устанавливает указатель в файле fp в позицию, отстоящую на n количество байт от текущей, и также направление перемещения (вперед или назад) которое указывается в m, в нем может быть задано одно из трех значений: 0, 1, 2 или одной из трех символических констант, указанных в библиотеке stdio.h:
- SEEK_SET = 0 – указатель к началу файла;
- SEEK_CUR = 1 – указатель на текущую позицию в файле;
- SEEK_END = 2 — указатель к концу файла.[15]
Данная функция fseek() используется для ввода/вывода потоковых данных. Для работы не с потоковыми данными следует использовать функцию lseek(). После функции fseek() можно выполнять операции обновления в файлах, открытых для обновления. При удачном завершении работы fseek() возвращает ноль, в противном случае функция возвращает код ошибки. Тогда глобальная переменная errno принимает одно из следующих значений:
- EBADF — неверный указатель файла;
- EINVAL — неверный аргумент функции;
- ESPIPE — поиск на устройстве запрещен.
- Функция ftell()
Вид функции: long int i = ftell(fp);
Возвращает текущее значение указателя файла fp (т. е. номер текущей позиции) в виде значения типа long int. Отсчет идет в байтах от начала файла. Возвращаемое значение может быть использовано затем в функции fseek(). Если обнаружены ошибки, функция возвращает значение -1L и присваивает глобальной переменной errno положительное значение.
- Функция fscanf()
Вид функции: fscanf(fp, Control, arg1, arg2, ... , argn);
Функция читает данные из файла c указателем fp, преобразует их по форматам, записанным в управляющей строке Control, и отформатированные данные записывает в аргументы arg1, ... , argn.[16]
- Функция fprintf()
Вид функции: fprinf(fp, Control, arg1, arg2, ... , argn);
Выводит данные в файл c указателем fp, преобразует аргументы arg1, ... , argn к форматам, которые записаны в управляющей строке Control, и отформатированные данные записывает в файл.
- Функция rewind()
Вид функции: rewind(fp);
Устанавливает указатель позиционирования в файле с указателем fp на начало потока. Вызов функции rewind(fp) эквивалентен вызову функции fseek(fp, 0L, SEEK_SET) за исключением того, что rewind() сбрасывает индикатор конца файла и индикаторы ошибок, а fseek() сбрасывает только индикатор конца файла. После функции rewind() можно выполнять операции обновления для файлов, открытых для обновления. Функция не возвращает никакого значения.
- Функция remove()
Вид функции: remove(FILENameString);
Данная функция удаляет файл с именем FILENameString. Перед удалением удаляемый файл должен быть закрыт. Строка FILENameString должна содержать полный путь к файлу с сохранением регистров. При отсутствии ошибок и выполнении задания функция возвращает ноль, а в случае ошибки – 1. При этом глобальная переменная errno принимает следующие значения:
- EACCES — невозможно удалить;
- ENOENT — файл с таким именем отсутствует.
- Функция FILElength()
Вид функции: long FILElength(fp);
Функция возвращает длину файла с указателем fp в байтах. Для работы функции требуется подключить файл io.h. В случае ошибки функция возвращает −1, и глобальная переменная errno принимает значение EBADF – неверный указатель файла.
- Функция ferror()
Вид функции: ferror(fp);
Функция тестирует поток на ошибки чтения-записи. Если индикатор ошибки устанавливается, то он остается в таком положении, пока не будут вызваны функции clearerr() или rewind(), или до того момента, пока поток не закроется. Если в файле была обнаружена ошибка, то функция ferror() возвращает ненулевое значение.
- Функция freopen()
Вид функции: FILE *freopen(const char *FILEname, const char *mode, FILE *stream);
Эта функция выставляет файл, который задан в первом параметре, на место выбранного открытого потока. Также функция будет закрывать потом не взирая на его состояние открыт/закрыт. Такая функция может быть полезна для замены файлов связанных со стандартными средствами ввода/вывода stdin, stdout или stderr. Условия необходимые для открытия файла аналигичны функции fopen(). После удачного выполнения задачи функция возвращает указатель FILE (как и функция fopen()), при неуспешном — NULL).[17]
- Функция feof()
Вид функции: feof(fp);
Обнаруживает конец файла с указателем fp: тестирует поток на возникновение индикатора конца файла (который наступает после прочтения последней записи). Как только индикатор установлен, операции чтения файла возвращают индикатор до тех пор, пока не выполнена функция rewind() – "перемотка" в начало файла, или пока файл не будет закрыт. Индикатор конца файла переустанавливается с каждой операцией ввода. Функция возвращает ненулевую величину, если индикатор конца файла был обнаружен при последней операции чтения, в противном случае – ноль.[18]
- Функция ferror()
Вид функции: ferror(FILE *fp);
Функция выдает ненулевое значение, если операция с файловым потоком завершается с ошибкой (например, возникает ошибка чтения файла). Для обработки ошибок ввода/вывода следует записать эту функцию перед блоком работы с файлом в виде:
