Нижегородский государственный технический университет имени Р. Е. Алексеева
Опубликован: 26.03.2015 | Доступ: свободный | Студентов: 6249 / 1178 | Длительность: 07:05:00
ISBN: 978-5-9556-0173-1
Специальности: Программист, Преподаватель
Лекция 7:

Работа с файловыми потоками. Пользовательские функции

< Лекция 6 || Лекция 7: 12
Аннотация: Очень часто бывают задачи, в которых неоходимо производить запись в файл или чтение из файла. Например, если программа производит много вычислений, по результатам которых нужно постороить график в MS Excel. Другой пример, когда программа работает с большим набором данных, которые хранятся в файлах. Пользовательские функции дают возможность упростить код программы, уменьшить ее объемы, визуально улучшить читаемость кода. Цель данной лекции – ознакомить студентов с понятиями файлового потока и пользовательской функции; показать, как работать с файлами и создавать свои пользовательские функции.

Занятие 1. Работа с файловыми потоками

Программа С++ может взаимодействовать не только с экраном DOS, но и с файлами. Мы будем рассматривать работу с текстовыми файлами (*.txt) и таблицами MS Excel (*.xls).

К примеру, требуется составить программу для решения дифференциального уравнения. Программа выдаст в качестве ответа набор чисел. Количество чисел может быть любым числом – и 10, и 200. Поэтому разумно в этом случае печатать эти данные не столько на экран DOS, сколько в файл *.xls, а затем в MS Excel строить график. При этом говорят, что программа выводит в файл данные.

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

Чтобы программа могла взаимодействовать с файлом, неоходимо использовать переменную типа файловый поток. Такая переменная задается ключевым словом fstream.

Для работы с файловым потоком необходимо:

  1. подключить библиотеку fstream:
    #include <fstream>
  2. объявить переменную типа файловый поток:
    fstream f;
  3. открыть файл:
    • для записи в файл:
      f.open("1.txt", ios::out);
    • для чтения из файла:
      f.open("1.txt", ios::in);
  4. произвести запись в файл или чтение из файла:
    • для записи в файл:
      f<<"x="<<x;
    • для чтения из файла:
      f>>x;
  5. закрыть файл: f.close();

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

f.open("1.txt", ios::app);

Пример 1. Считать из файла число и показать его на экране.

Решение. Сначала рассмотрим, как выполнить эту задачу в Visual Studio, затем – в Borland C++.

Создадим проект в Visual Studio, назовем его "8.1". При этом генерируется папка с нашим проектом. Открываем папку 8.1\8.1 и создаем текстовый документ, называем его 1.txt, как показано на рис. 7.1.

Создание текстового файла в папке с проектом

Рис. 7.1. Создание текстового файла в папке с проектом

Открываем файл 1.txt и записываем одно число, например, -3.27, как показано на рис. 7.2.

Исходный текстовый файл для примера 1

Рис. 7.2. Исходный текстовый файл для примера 1

Сохраняем и закрываем файл. Теперь переходим в приложение Visual Studio и в нашем проекте прописываем код программы.

Код программы для примера 1:

// 8.1.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{ 
	double x;
	fstream f;
	f.open("1.txt", ios::in);
	f>>x;
	f.close();
	cout<<"x="<<x<<endl;
	return 0;
}

Результат выполнения программы:


Чтобы работать с файлами в Borland C++, создадим папку F:/BC/FILES. Эта папка предназначена для хранения файлов, с которыми будет взаимодействовать наша программа. Создаем файл 1.txt в папке F:/BC/FILES, записываем в него число -3.27.

При открытии файла необходимо записать имя файла как FILES/1.txt, чтобы наша программа искала текстовый файл именно в этой папке.

Код программы:

#include <iostream.h>
#include <fstream.h>
int main()
{ 
	double x;
	fstream f;
	f.open("FILES/1.txt", ios::in);
	f>>x;
	f.close();
	cout<<"x="<<x<<endl;
	return 0;
}

Результат выполнения программы:


Пример 2. Составить программу, которая производит запись двух чисел в файлы *.txt и *.xls.

Решение. Обозначим числа как a и b, зададим а=7,2; b=-10.89. Файлы не будем предварительно создавать, т.к. они возникнут автоматически при запуске нашей программы. Создаем новый проект 8.2 в Visual Studio.

Объявим два файловых потока ftxt – для записи в текстовый файл 1.txt, fxls – для записи в табличный файл 2.xls.

Сделаем так, чтобы в файле 1.txt появилась надпись:

a=7.2 b=-10.89

В файле 2.xls выведем каждый кусочек сообщения в разные ячейки. Для этого следует использовать символ табуляции "\t".

Код программы для примера 2:

// 8.2.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
	double a, b;
	fstream ftxt, fxls;
	a=7.2;
	b=-10.89;
	cout<<"a="<<a<<" b="<<b<<endl;
	ftxt.open("1.txt", ios::out);
	fxls.open("2.xls", ios::out);
	ftxt<<"a="<<a<<" b="<<b;
	fxls<<"a=\t"<<a<<"\tb=\t"<<b;
	ftxt.close();
	fxls.close();
	return 0;
}

Результат выполнения программы:

экран DOS:


текстовый файл 1.txt:


табличный файл 2.xls:


Примечание. Файлы 1.txt и 2.xls создаются в папке с проектом 8.2\8.2, как показано на рис. 7.3.

Созданные программой файлы в папке с проектом

Рис. 7.6. Созданные программой файлы в папке с проектом

Решим данную задачу в Borland C++.

Код программы:

#include <iostream.h>
#include <fstream.h>
int main()
{
	double a, b;
	fstream ftxt, fxls;
	a=7.2;
	b=-10.89;
	cout<<"a="<<a<<" b="<<b<<endl;
	ftxt.open("FILES/1.txt", ios::out);
	fxls.open("FILES/2.xls", ios::out);
	ftxt<<"a="<<a<<" b="<<b;
	fxls<<"a=\t"<<a<<"\tb=\t"<<b;
	ftxt.close();
	fxls.close();
	return 0;
}

Результат выполнения программы:

экран DOS:


текстовый файл 1.txt:


табличный файл 2.xls:


Примечание. Т.к. в примере 2 мы задали имя текстового файла 1.txt так же, как в примере 1, то после выполнения программы примера 2 в папке FILES будет находиться два файла. Файл 1.txt запишется заново. При этом потеряется число -3.27, которое мы печатали для примера 1.

В следующих примерах будем приводить коды программ в среде Visual Studio.

Пример 3. Построить таблицу значений функции y=\sin x при 0\le x\le 2 с шагом 0,1.

Решение. Данный пример решается с помощью циклического алгоритма. Будем использовать цикл for. Построим таблицу значений функции на экране, а также в файле 1.xls и построим график в MS Excel.

Блок-схема:


Код программы:

// 8.3.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
	double x, y;
	fstream f;
	f.open("1.xls", ios::out);
	cout<<setw(10)<<"x"<<setw(10)<<"y"<<endl;
	f<<"x"<<"\t"<<"y"<<endl;
	for(x=0; x<=2; x=x+0.1){
		y=sin(x);
		cout<<setw(10)<<x<<setw(10)<<y<<endl;
		f<<x<<"\t"<<y<<endl;
	}
	f.close();
	return 0;
}

Результат выполнения программы:

экран DOS:


табличный файл 1.xls:


Файл 1.xls с построенным графиком:


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

Решение. Матрица а является двумерным массивом, состоящим из пяти строк и пяти столбцов. Проинициализируем массив по формуле a[i][j]=7\sin(2,3ij). Массив и все результаты вычислений будем выводить в файл 1.xls.

Блок-схема:


Код программы:

// 8.4.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
	double a[5][5], s, p;
	int i, j, k;
	fstream f;
	f.open("1.xls", ios::out);
	cout<<"matrix:"<<endl;
	f<<"матрица:"<<endl;
	for(i=0; i<5; i=i+1){
		for(j=0; j<5; j=j+1){
			a[i][j]=7.0*sin(2.3*i*j);
			cout<<setw(10)<<a[i][j];
			f<<'\t'<<a[i][j];
		}
		cout<<endl;
		f<<endl;	
	}
	s=0;
	for(i=0; i<5; i=i+1){
		for(j=0; j<5; j=j+1){
			if(a[i][j]>0){
				s=s+a[i][j];
			}
		}
	}
	cout<<"s="<<s<<endl;
	f<<"Сумма положительных=\t"<<s<<endl;
	p=1;
	for(i=0; i<5; i=i+1){
		for(j=0; j<5; j=j+1){
			if(i==j){
				p=p*a[i][j];
			}
		}
	}
	cout<<"p="<<p<<endl;
	f<<"Произв. на гл. диаг.=\t"<<p<<endl;
	k=0;
	for(i=0; i<5; i=i+1){
		for(j=0; j<5; j=j+1){
			if(a[i][j]>2){
				k=k+1;
			}
		}
	}
	cout<<"k="<<k<<endl;
	f<<"Количество элем.>2 =\t"<<k<<endl;
	f.close();
	return 0;
}

Результат выполнения программы:

экран DOS:


табличный файл 1.xls:


Примечание. Если данный код запустить в программе Borland C++, то русский текст следует заменить латиницей.

< Лекция 6 || Лекция 7: 12
Никита Беллонский
Никита Беллонский

Лекция 4. Упражнение №4.

Составил блок-схему и по ней написал программу. Работает корректно, но если подбираю значения, чтобы выходила сумма меньше -2, на выводе значится: "-na n(i nd)". 

Я так понимаю, это потому что в выражении выполняется извлечение квадратного корня из отрицательного числа. Но что значит "-na n(i nd)"? Почему вывод именно такой? Машина всегда так сообщает о "неудачных" вычислениях? 

Антон Биганов
Антон Биганов

в лекции 2.

"Таблица 2.4. Выполнение блок-схемы с предусловием для примера 9" - в блоке условия стоит а<10, при таком условии последяя строка {S=17, R=3} на экран выведена не будет.

 

Елена Сергеева
Елена Сергеева
Россия, Таганрог, ТРТУ, 2003
Сергей Ишутин
Сергей Ишутин
Россия, Воронеж