Основные теоретические сведения. На практике встречается множество задач исследовательского характера направленных на поиск оптимального алгоритма обработки данных

 

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

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

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

 

Работа с файлами

 

В лабораторной работе №1 в разделе «Ввод/вывод информации на экран» были рассмотрены основные понятия о системе ввода/вывода и потоках. Там же упоминалось, что функции ввода/вывода информации на экран можно также использовать для работы с файлами. Рассмотрим теперь более подробно вопрос: как это делать?

В листинге 24 дан пример программы, позволяющей оператору записывать и читать данные из текстового файла.

После запуска программы оператору предлагается сделать выбор: ввести 1 для записи, 2 для чтения и 0 для выхода из программы. Если оператор выбирает запись, то в директории программы формируется текстовый файл Out.txt в который записываются цифры от 0 до 9. Если оператор выбрал чтение, то данные читаются из файла Out.txt и записываются в массив nArray.

Листинг 31

/*Пример записи и чтения информации из файла*/

#include <fstream.h> // Библиотека функций для работы с файлами

void main( void )

{

int nKey; // Ключ, позволяющий оператору осуществлять выбор:

// записать данные, прочитать или выйти из программы

int nArray[10]; // Массив для прочитанных данных

 

// Цикл до тех пор пока оператор не решил выйти из программы

while ( nKey != 0 )

{

// Формирование меню: Введите 1 для записи, 2 для чтения 0 для выхода

cout << "Enter 0 for exit, 1 for write and 2 for read\n";

cin >> nKey;

int i;

if ( nKey == 1) // Оператор выбрал запись

{

// Открыть поток для записи в файл out.txt

ofstream OutFile("out.txt");

for ( i = 0; i < 10; i++ )

{

OutFile << i <<"\n"; // Запись

}

OutFile.close(); // Закрыть поток

} else if ( nKey == 2 ) // Оператор выбрал чтение

{

// Открыть поток для чтения из файла out.txt

ifstream InFile("out.txt");

for ( i = 0; i < 10; i++ )

{

// Чтение данных из файла в массив nArray

InFile >> nArray[i];

// Вывод прочитанных данных на экран

cout << nArray[i] << '\n';

}

InFile.close(); // Закрыть поток

}

}

}

 

 

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

Рассмотрим более подробно код этой программы.

Запись происходит в участке кода:

 

// Открыть поток для записи в файл out.txt

ofstream OutFile("out.txt");

for ( i = 0; i < 10; i++ )

{

OutFile << i <<"\n"; // Запись

}

OutFile.close(); // Закрыть поток

 

Здесь совершенно новой и непонятной может показаться строка ofstream OutFile("out.txt"). Из комментария следует, что в данной строке происходит открытие потока. Обратите внимание, что если убрать часть ("out.txt") и предположить, что ofstream это тип данных, то строка похожа на объявление переменной OutFile типа ofstream. Отчасти это верно, за исключением того, что ofstream это не тип, а класс, а OutFile — объект. Так как изучение классов и объектов выходит за рамки данного семестра, то студентам рекомендуется пока воспринимать ofstream как особый тип данных такой же, как int, double, char или bool, а термин «объект» — как специфическую переменную.

Итак, ofstream (output file stream) — это «тип данных» описывающий поток вывода, который связывается с файлом. Подобно записи int nNum, создающей целочисленную переменную nNum, запись ofstream OutFile создает поток вывода OutFile. Попутно с созданием потока идет его инициализация ("out.txt") т.е. в данном случае поток связывается с файлом out.txt. Если файл не существует, то он будет создан. Если файл существует, то его содержимое будет удалено.

Собственно запись в файл аналогична конструкции cout << Данные. В лабораторной работе №1 упоминалось, что операторы, осуществляющие вывод информации на экран также могут использоваться для вывода на принтер или в файл. Теперь вы можете убедиться, что это действительно так.

Специфика потоков открываемых конструкцией ofstream ИмяПотока заключается в том, что их необходимо закрывать. В нашем примере это делается в строке OutFile.close().

Чтение из файла во многом аналогично записи. В листинге 24 оно происходит на участке:

 

// Открыть поток для чтения из файла out.txt

ifstream InFile("out.txt");

for ( i = 0; i < 10; i++ )

{

// Чтение данных из файла в массив nArray

InFile >> nArray[i];

// Вывод прочитанных данных на экран

cout << nArray[i] << '\n';

}

InFile.close(); // Закрыть поток

 

ifstream (input file stream) — это «тип данных» описывающий поток ввода, который связывается с файлом. В нашем случае поток ввода InFile связывается с тем же файлом out.txt.

В ходе чтения InFile >> nArray[i], данные из файла заносятся в массив.

Анализируя листинг 24, следует учитывать некоторые подводные камни.

Во-первых, если файл, из которого производится чтение, не существует, то содержимое массива nArray не изменится.

Во-вторых, в процессе чтения вы должны точно знать объем записанных в файл данных. Если в файле записано 10 чисел, а читается 11, то содержимое 11-го элемента массива nArray будет непредсказуемо.

Как видите, запись и чтение из файла не многим сложнее вывода на экран и ввода с клавиатуры.

 

Решение типовых задач

 

Задача 1. Дана функция: y = x2. Провести табуляцию функцию на интервале [a,b] с шагом Δx = (b - a)/10. Занести результат в текстовый файл. Построить график табулированной функции.

 

Решение.

 

Листинг 32

/*Пример записи и чтения информации из файла*/

#include <fstream.h>

#include <math.h>

void main( void )

{

// Переменные для границ интервала и шага аргумента

double dA, dB, dDeltaX;

// Ввод данных

cout << "Please input a, b (b > a)\n";

cin >> dA >> dB;

// Проверка корректности введенных данных

if ( dB <= dA )

{

cout << "Wrong inteval\n";

return;

}

// Расчет шага аргумента

dDeltaX = (dB - dA)/10.;

// Открываем поток

ofstream OutFile("function.txt");

for ( int i = 0; i <= 10; i++ )

{

// Записываем в файл очередное значение аргумента и функции

OutFile << dA + i * dDeltaX << ‘\t’ << pow(dA + i * dDeltaX, 2 ) <<"\n";

}

// Закрываем поток

OutFile.close();

}

 

 

Содержимое файла function.txt:

 

0 0

0.2 0.04

0.4 0.16

0.6 0.36

0.8 0.64

1 1

1.2 1.44

1.4 1.96

1.6 2.56

1.8 3.24

2 4

 

График функции:

Рис. 18

 


 

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

 

Решение.

 

Листинг 33

/*Пример записи и чтения информации из файла*/

#include <fstream.h>

void main( void )

{

// Массив для хранения значений аргумента и функции

double nArray[11][2];

// Открываем поток

ifstream InFile("function.txt");

for ( int i = 0; i <= 10; i++ )

{

// Читаем и в массив значение аргумента

InFile >> nArray[i][0];

// Читаем и в массив значение функции

InFile >> nArray[i][1];

// Выводим данные на экран

cout << nArray[i][0] << ‘\t’ << nArray[i][1] << "\n";

}

// Закрываем поток

InFile.close();

}

 

 


Задание на лабораторную работу №5

 

Задача 1. Разработать алгоритм и написать по нему программу табулирования функции f(x) на интервале [a, b] с шагом Δx = (b - a)/10. Результат табулирования записать в текстовый файл. Вид функции выбрать в соответствии с таблицей 5.1. По результатам записи в файл построить график.

 

Примечание! Помните, что аргумент тригонометрических функций выражается в радианах.

Примечание! Для функций вида 1/a необходимо выполнять проверку условия a ≠ 0.

 

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

 

Оформить протокол лабораторной работы.

 

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

 


Варианты заданий

 

Таблица 5.1. Варианты заданий к задаче 1

  № Функция     №   Функция   №   Функция
   

 

Контрольные вопросы

 

1. Вы хотите записать данные в текстовый файл. Ваши действия?

2. Вы хотите прочитать данные из текстового файла. Ваши действия?

 


Лабораторная работа №8

 

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

 

Задачи:

1) Разработать алгоритм и написать по нему программу нахождения производной функции в точке.

2) Разработать алгоритм и написать по нему программу численного дифференцирования функции на отрезке.