Файловый ввод — вывод
В программировании нередко приходится иметь дело с файлами. В данной статье мы рассмотрим основный принципы и методы файлового ввода — вывода.
Прежде, чем использовать файловый ввод — вывод, подключаем заголовочный файл fstream.
Начинаем работать
Для начала объявим потоки:
ifstream и ofstream — это классы. Значит созданные нами fin и fout — это экземпляры класса, или объекты. Это означает, что для них определены методы.
Воспользуемся методом открытия файла — open(). В скобках нам необходимо указать имя требуемого файла в кавычках.
Также одним из методов является is_open(). Данный метод проверяет, удалось ли открыть файл. Возвращает логическое значение.
Иначе, нам удалось открыть файл. Предположим, что в нашем файле лежали некоторые числа, и мы хотим узнать их сумму и вывести её на экран. Стоит отметить, что файл должен лежать в одной папке с вашем проектом (в противном случае, можно указать путь к файлу).
Всегда, после использования потока, закрываем его методом close().
Теперь рассмотрим вывод в файл. На самом деле, он не сильно отличается от ввода. Открываем файл для вывода:
ЯТП Лекции (Шамбуева, Петелина) / ВВОД_ВЫВОД_ФАЙЛЫ
Так как передачи выполняются с разной скоростью, то используется буферная область (область оперативной памяти), из которой программа получает данные при вводе, либо в которую она передает данные при выводе.
ВВОД: ВнУ—— ===== Программа
В С++ ввод и вывод происходят через ПОТОКИ. Поток представляет собой направленное движение символов или других данных. Поток данных, поступающих в программу, наз. ПОТОКОМ ВВОДА (входным потоком), данные, направленные из программы, образуют ПОТОК ВЫВОДА(выходной поток).
Какие преимущества даёт использование потоковых классов для ввода –вывода вместо традиционных функций С?
1)простота использования (не надо использовать форматы при выводе, каждый объект сам знает,как он должен выглядеть на экране ).
2)можно перегружать операции вставки (<<)и извлечения (>>)для работы с создаваемыми классами.
В программе можно определить потоки ввода или вывода данных в файл. Файл –именованная совокупность логически связанных данных, специальным образом организованная на внешнем носителе.
Использование файлов гораздо удобнее, т.к. информация, записанная в файл, сохраняется после того, как программа закончит свою работу и может быть использована и другими программами. Файлы облегчают работу с большими объемами данных: набирается информация в файл, а затем из него считывается, что позволяет избежать повторного ввода её с клавиатуры.
Если для ввода информации из файла (или записи её в файл) хотим воспользоваться потоком, необходимо выдержать некоторую дисциплину:
(1)объявить поток (переменную потока);
переменные потока ввода из файла имеют тип ifstream (input-file-stream); переменные потока вывода в файл имеют тип ofstream (output-file-stream): ifstream fin;
ofstream fout;
Типы ifstream и ofstream объявлены в библиотеке с заголовочным файлом fstream,поэтому в программу необходимо включить директиву
#include <fstream>
(2)связать поток с физическим файлом c помощью функции OPEN() и открыть файл для чтения или записи:
перед началом чтения из файла fin.open(“dan.txt” [,ios::in] );
(Входной файл dan.txt открывается для чтения)
перед записью в файл fout.open(“rez.txt” [, ios ::out | ios : :trunc] );
Параметры в [ ] можно не писать, приведены их значения по умолчанию.
При этом open () создаёт новый файл для вывода информации, если же файл с таким именем уже существует, функция open() сделает его пустым.
После того, как файл открыт, программа идентифицирует его по имени потока, связанного с файлом.
После обращения к функции open всегда надо проверить, был ли на самом деле открыт файл. Это можно сделать с помощью функции fail().Если обращение к функции open() будет выполнено неудачно, fail() вернёт в программу значение true. Например, после fin.open(“dan.txt”) надо
Аналогично после fout.open(“rez.txt”) проверяют был ли открыт файл :
При успешном открытии файла программа продолжит свою работу.
(3)После открытия файла для чтения можно считывать информацию из файла с помощью операции извлечения >>: fin>>s; (или другим способом – чтение символов и строк).
После открытия файла для записи можно записывать информацию в этот файл с помощью операции вставки <<: fout<<N;
После считывания или записи информации
(4)файл нужно закрыть с помощью функции close(), при этом прекращается связь файла с потоком: fin.close(); fout.close();
Если программа закончит работу и не закроет файл, то операционная система закроет файл автоматически. Однако дисциплина работы с файлами рекомендует закрывать файл, когда он более не нужен: это поможет в ситуации, когда программа будет закончена аварийно , если файл не будет закрыт, он может остаться в искаженном состоянии; кроме того ,может потребоваться сначала записать информацию в файл ,а затем её считать обратно в программу. Для этого программа после записи информации в файл должна его закрыть, а затем связать с ним поток ввода с помощью функции open.
Чтение из входного потока выполняется
=с помощью операции >>;
=с использованием функций – методов класса istream.
Чтение чисел : прочитать всю числовую информацию из файла до конца файла: while (fin>>…. ) <обработка считанной информации>
int num, sum=0;
while (fin>>num ) sum+=num; //суммируются вводимые числа
Выражение fin>>num с операцией извлечения >> одновременно является действием и логическим условием : оно указывает, что из потока ввода надо взять очередное число, а также является условием, которое может выполняться или не выполняться. Если в потоке есть очередное число, оно считывается, условие выполняется и цикл делает ещё одну итерацию. Если в потоке нет больше чисел, условие не выполняется и цикл завершается.
Ввод-Вывод символов.
Для чтения символа из файла используется функция-член класса istream get(char sym), которая считывает один символ из потока и записывает его в символьную переменную sym.В отличие от операции извлечения >> функция get() считывает любой символ независимо от его значения (не пропускает пробел или символ новой строки ‘\n’, если они окажутся входными).
Чтение символа из файла: fin.get (sym) ; С помощью функции get()можно определить конец строки: организовать цикл, который по очереди будет считывать символы входной строки, пока не встретится символ новой строки ‘\n’.
Функция –член put() аналогична функции get(),но предназначена для вывода символа, она получает аргумент – выражение типа char и выводит в поток символ-значение аргумента.Например, fout.put(‘a’);
fout<<’a’;
2 способ Функция eof() (end of file) позволяет определить, вся ли информация прочитана из файла. 1 способ работает при вводе числовых данных, а функция eof() применяется в основном для работы с текстовой информацией, не требует никаких аргументов и записывается в виде fin.eof(). Это логическое выражение , оно может быть использовано в циклах while, do-while, в условии в if-else. Это выражение выполняется( т.е.оно истинно), если программа предприняла попытку прочитать информацию после конца файла ввода, во всех других ситуациях значением этого выражения является ложь. Обычно функция eof() используется совместно с операцией не (отрицание, обозначается !).Например, всю информацию из файла можно прочитать с помощью следующего цикла:
fin.get(ch); // первый символ считываем до цикла
while (! fin.eof())
fin.get(ch); >
Чтение строк fin.getline (s,ds); – с сохранением пробелов в строке.
Для форматирования данных можно использовать:
1)флаги; 2)форматирующие методы; 3)манипуляторы. Удобнее всего манипуляторы. Они включаются в цепочку операций включения в поток и извлечения из него для форматирования данных.
Есть простые манипуляторы: dec (10-ая с.с.), oct (8ая с.с.),hex (16-ая с.с.)-при вводе и выводе. Изменения с.с. действуют до следующего явного изменения.
endl – при выводе включаект в поток символ новой строки и выгружает буфер.
Есть параметризованные манипуляторы:
setfill(int)-устанавливает символ заполнитель с кодом, равным значению параметра.
setprecision(int) — устанавливает максимальное количество цифр в дробной части для вещ. чисел с фиксированной точкой (флаг fixed) , или общее кол-во значащих цифр в мантиссе в форме с мантиссой и порядком.
setw(int) – устанавливает максимальную ширину поля вывода.
Функции в качестве формальных параметров могут иметь потоки, но эти параметры должны передаваться функции по ссылке, а не по значению. Параметры для потоков ввода из файла могут иметь тип ifstream, а для вывода в файл – ofstream.
Если формальный параметр есть поток ввода типа istream, то в качестве соответствующего фактического параметра может быть передан и поток cin, и поток ввода из файла типа ifstream.
Если формальный параметр есть поток вывода типа ostream, то в качестве соответствующего фактического параметра может быть передан и поток cout, и поток вывода в файл типа ofstream.
В файле записаны матрицы: размеры матрицы в строке , а следом –элементы матрицы по строкам. Выбрать матрицы симметрические и записать их в выходной файп.
Работа с файлами в С++
Большинство компьютерных программ работают с файлами, и поэтому возникает необходимость создавать, удалять, записывать читать, открывать файлы. Что же такое файл? Файл – именованный набор байтов, который может быть сохранен на некотором накопителе. Ну, теперь ясно, что под файлом понимается некоторая последовательность байтов, которая имеет своё, уникальное имя, например файл.txt . В одной директории не могут находиться файлы с одинаковыми именами. Под именем файла понимается не только его название, но и расширение, например: file.txt и file.dat — разные файлы, хоть и имеют одинаковые названия. Существует такое понятие, как полное имя файлов – это полный адрес к директории файла с указанием имени файла, например: D:\docs\file.txt . Важно понимать эти базовые понятия, иначе сложно будет работать с файлами.
Для работы с файлами необходимо подключить заголовочный файл <fstream> . В <fstream> определены несколько классов и подключены заголовочные файлы <ifstream> — файловый ввод и <ofstream> — файловый вывод.
Файловый ввод/вывод аналогичен стандартному вводу/выводу, единственное отличие – это то, что ввод/вывод выполнятся не на экран, а в файл. Если ввод/вывод на стандартные устройства выполняется с помощью объектов cin и cout , то для организации файлового ввода/вывода достаточно создать собственные объекты, которые можно использовать аналогично операторам cin и cout .
Например, необходимо создать текстовый файл и записать в него строку Работа с файлами в С++ . Для этого необходимо проделать следующие шаги:
- создать объект класса ofstream ;
- связать объект класса с файлом, в который будет производиться запись;
- записать строку в файл;
- закрыть файл.
Почему необходимо создавать объект класса ofstream , а не класса ifstream ? Потому, что нужно сделать запись в файл, а если бы нужно было считать данные из файла, то создавался бы объект класса ifstream .
Назовём объект – fout , Вот что получится:
Для чего нам объект? Объект необходим, чтобы можно было выполнять запись в файл. Уже объект создан, но не связан с файлом, в который нужно записать строку.
Через операцию точка получаем доступ к методу класса open(), в круглых скобочках которого указываем имя файла. Указанный файл будет создан в текущей директории с программой. Если файл с таким именем существует, то существующий файл будет заменен новым. Итак, файл открыт, осталось записать в него нужную строку. Делается это так:
Используя операцию передачи в поток совместно с объектом fout строка Работа с файлами в С++ записывается в файл. Так как больше нет необходимости изменять содержимое файла, его нужно закрыть, то есть отделить объект от файла.
Итог – создан файл со строкой Работа с файлами в С++ .
Шаги 1 и 2 можно объединить, то есть в одной строке создать объект и связать его с файлом. Делается это так:
Объединим весь код и получим следующую программу.
Осталось проверить правильность работы программы, а для этого открываем файл cppstudio.txt и смотрим его содержимое, должно быть — Работа с файлами в С++ .
Для того чтобы прочитать файл понадобится выполнить те же шаги, что и при записи в файл с небольшими изменениями:
- создать объект класса ifstream и связать его с файлом, из которого будет производиться считывание;
- прочитать файл;
- закрыть файл.
В программе показаны два способа чтения из файла, первый – используя операцию передачи в поток, второй – используя функцию getline() . В первом случае считывается только первое слово, а во втором случае считывается строка, длинной 50 символов. Но так как в файле осталось меньше 50 символов, то считываются символы включительно до последнего. Обратите внимание на то, что считывание во второй раз ( строка 17 ) продолжилось, после первого слова, а не с начала, так как первое слово было прочитано в строке 14 . Результат работы программы показан на рисунке 1.
Рисунок 1 — Работа с файлами в С++
Программа сработала правильно, но не всегда так бывает, даже в том случае, если с кодом всё впорядке. Например, в программу передано имя несуществующего файла или в имени допущена ошибка. Что тогда? В этом случае ничего не произойдёт вообще. Файл не будет найден, а значит и прочитать его не возможно. Поэтому компилятор проигнорирует строки, где выполняется работа с файлом. В результате корректно завершится работа программы, но ничего, на экране показано не будет. Казалось бы это вполне нормальная реакции на такую ситуацию. Но простому пользователю не будет понятно, в чём дело и почему на экране не появилась строка из файла. Так вот, чтобы всё было предельно понятно в С++ предусмотрена такая функция — is_open() , которая возвращает целые значения: 1 — если файл был успешно открыт, 0 — если файл открыт не был. Доработаем программу с открытием файла, таким образом, что если файл не открыт выводилось соответствующее сообщение.
Результат работы программы показан на рисунке 2.
Рисунок 2 — Работа с файлами в С++
Как видно из рисунка 2 программа сообщила о невозможности открыть файл. Поэтому, если программа работает с файлами, рекомендуется использовать эту функцию, is_open() , даже, если уверены, что файл существует.
Режимы открытия файлов
Режимы открытия файлов устанавливают характер использования файлов. Для установки режима в классе ios_base предусмотрены константы, которые определяют режим открытия файлов (см. Таблица 1).
| Константа | Описание |
|---|---|
| ios_base::in | открыть файл для чтения |
| ios_base::out | открыть файл для записи |
| ios_base::ate | при открытии переместить указатель в конец файла |
| ios_base::app | открыть файл для записи в конец файла |
| ios_base::trunc | удалить содержимое файла, если он существует |
| ios_base::binary | открытие файла в двоичном режиме |
Режимы открытия файлов можно устанавливать непосредственно при создании объекта или при вызове функции open() .
Режимы открытия файлов можно комбинировать с помощью поразрядной логической операции или | , например: ios_base::out | ios_base::trunc — открытие файла для записи, предварительно очистив его.
Объекты класса ofstream , при связке с файлами по умолчанию содержат режимы открытия файлов ios_base::out | ios_base::trunc . То есть файл будет создан, если не существует. Если же файл существует, то его содержимое будет удалено, а сам файл будет готов к записи. Объекты класса ifstream связываясь с файлом, имеют по умолчанию режим открытия файла ios_base::in — файл открыт только для чтения. Режим открытия файла ещё называют — флаг, для удобочитаемости в дальнейшем будем использовать именно этот термин. В таблице 1 перечислены далеко не все флаги, но для начала этих должно хватить.
Обратите внимание на то, что флаги ate и app по описанию очень похожи, они оба перемещают указатель в конец файла, но флаг app позволяет производить запись, только в конец файла, а флаг ate просто переставляет флаг в конец файла и не ограничивает места записи.
Разработаем программу, которая, используя операцию sizeof() , будет вычислять характеристики основных типов данных в С++ и записывать их в файл. Характеристики:
- число байт, отводимое под тип данных
- максимальное значение, которое может хранить определённый тип данных.
Запись в файл должна выполняться в таком формате:
Такая программа уже разрабатывалась ранее в разделе Типы данных С++ , но там вся информация о типах данных выводилась на стандартное устройство вывода, а нам необходимо программу переделать так, чтобы информация записывалась в файл. Для этого необходимо открыть файл в режиме записи, с предварительным усечением текущей информации файла (строка 14). Как только файл создан и успешно открыт (строки 16 — 20), вместо оператора cout , в строке 22 используем объект fout . таким образом, вместо экрана информация о типах данных запишется в файл.
Нельзя не заметить, что изменения в программе минимальны, а всё благодаря тому, что стандартный ввод/вывод и файловый ввод/вывод используются абсолютно аналогично. В конце программы, в строке 45 мы явно закрыли файл, хотя это и не обязательно, но считается хорошим тоном программирования. Стоит отметить, что все функции и манипуляторы используемые для форматирования стандартного ввода/вывода актуальны и для файлового ввода/вывода. Поэтому не возникло никаких ошибок, когда оператор cout был заменён объектом fout .
Работа с файлами в си ввод и вывод в файл в си
В этой статье мы узнаем, как считывать данные из файлов и записывать информацию в файлы в программах си. Файлы в си используются для того, чтобы сохранять результат работы программы си и использовать его при новом запуске программы . Например можно сохранять результаты вычислений , статистику игр.
Чтобы работать с файлами в си необходимо подключить библиотеку stdio.h
#include <stdio.h>
Чтобы работать с файлом в си необходимо задать указатель на файл по образцу
FILE *имя указателя на файл;
Например
FILE *fin;
Задает указатель fin на файл
Дальше необходимо открыть файл и привязать его к файловому указателю. Для открытия файла в си на чтение используется команда
Имя указателя на файл= fopen("путь к файлу", "r");
Например следующая команда
fin = fopen("C:\\Users\\user\\Desktop\\data.txt", "r");
откроет файл data.txt, находящийся на рабочем столе по пути C:UsersuserDesktop Чтобы узнать путь к файлу можно выбрать файл мышью нажать на правую кнопку мыши и выбрать свойства файла. В разделе Расположение будет указан путь к файлу. Обратите внимание , что в си путь указывается с помощью двух слешей.
После работы с файлом в си , необходимо его закрыть с помощью команды
fclose(имя указателя на файл)
Считывание информации из текстового файла в Си
Чтобы можно было считывать русские символы из файла, необходимо настроить работу с Кириллицей с помощью команды
setlocale(LC_ALL, "Russian");
При этом необходимо в начале программы подключить #include <iostream>
Оператор fscanf()
Для считывания слова из файла в си используется команда fscanf(). Эта команда аналогична команде ввода информации с клавиватуры в си scanf() только первый параметр это указатель на файл
fscanf(указатель на файл,"%формат ввода данных1% форматввода данных2…",&перменная1,&переменная2…);
Например команда
fscanf(fin,"%d%d%d",&a,&b,&c);
считает из файла, который привязан к указателю на файл fin строку из трех целочисленных переменных
Разберем пример программы, которая считывает из текстового файла data.txt в которые записаны три столбца цифр информацию и записывает ее в массивы. Для каждого столбца информации свой массив. Подробно о работе с массивами в Си.
#include <stdio.h>
#include <conio.h>
main()
< int a[10];
int b[10];
int c[10];
int i;
// определяем указатель на файл
FILE *fin;
// открываем файл на чтение
fin = fopen("C:\\Users\\user\\Desktop\\data.txt", "r");
// построчное считывание из файла
for (i=0;i<3;i++)
<
// считывание строки из трех значений файла и запись в массивы
fscanf(fin,"%d%d%d",&a[i],&b[i],&c[i]);
>
// вывод массивов на экран
for (i=0;i<3;i++)
<
printf("%d %d %d\n",a[i],b[i],c[i]);
>
getch();
// закрытие файла
fclose(fin);
>
Построковое считывание информации из файла в СИ.Функция fgets ( )
Оператор fscanf() считывает из файла слово , т.е. до первого встречного пробела.
Чтобы считать из файла всю строку из файла в Си используется конструкция
if ( NULL != fgets (строковая переменная, длина строки, указатель на файл ) )
<
действия при считывании строки
>
Например программа на Си которая считывает две строки из файла и выводит их на экран
#include <stdio.h>
#include <conio.h>
#include <iostream>
main()
<
// задаем строковые перменные
char st1[100];
char st2[100];
//определяем указатель на файл
FILE *fin;
// настриваем работу с Кириллицей
setlocale(LC_ALL, "Russian");
// открываем файл на чтение
fin = fopen("C:\\data.txt", "r");
// считываем первую строку из файла
if ( NULL != fgets ( st1, 100, fin ) )
<
// выводим строку на экран
printf("%s ",st1);>
// считываем вторую строку из файла
if ( NULL != fgets ( st2, 100, fin ) )
<
// выводим строку на экран
printf("%s\n",st2);>
// закрываем файл на чтение
fclose(fin);
>
Запись информации в текстовый файл в Си
Для записи данных в файл в Си, необходимо открыть файл в режиме записи
Имя указателя на файл= fopen("путь к файлу", "w");
Для записи в строку текстового файла используется команда fprnitf(), которая аналогична команде printf() вывод на экран в си только первый параметр это указатель на файл
fprintf (имя указателя на файл,”%формат ввода”, переменные);
Например запись в файл out.txt значение переменной а
a=10;
fout = fopen("C:\\Users\\user\\Desktop\\out.txt", "w");
fprintf (fout,”%d”, a);
Пример программы на си которая запрашивает два числа и записывает в файл out.txt оба эти числа и их сумму
#include <stdio.h>
#include <conio.h>
Вернуться к содержанию Перейти к уроку Ошибки в программах на си