Компания ALT Linux
Опубликован: 12.03.2015 | Доступ: свободный | Студентов: 485 / 21 | Длительность: 20:55:00
Лекция 3:

Программирование

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

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

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

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

3.4.1 Обработка текстовых файлов

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

fopen(filename, mode)

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

  • rt — открываемый текстовый файл используется в режиме чтения;
  • rt+ — открываемый текстовый файл используется в режиме чтения и записи;
  • wt — создаваемый пустой текстовый файл предназначен только для записи информации;
  • wt+ — создаваемый пустой текстовый файл предназначен для чтения и записи информации;
  • at — открываемый текстовый файл будет использоваться для добавления данных в конец файла; если файла нет, он будет создан;
  • at+ — открываемый текстовый файл будет использоваться для добавления данных в конец файла и чтения данных; если файла нет, он будет создан.

Функция fopen возвращает идентификатор файла (номер, присвоенный файлу). Существует три стандартных системных файла: стандартный ввод (stdin), стандартный вывод (stdout) и файл, отвечающий за вывод сообщений об ошибках (stderr), за которыми закреплены идентификаторы 0, 1 и 2 соответственно.

Для форматированного вывода информации в файл можно использовать функцию следующего вида:

fprintf (f, s1, s2)

десь f — идентификатор файла (значение идентификатора возвращается функцией fopen), s1 — строка вывода, s2 — список выводимых переменных.

В строке вывода вместо выводимых переменных указывается строка преобразования следующего вида:

%[флаг][ширина][.точность] тип.

Значения основных параметров строки преобразования (символы управления форматированием) приведены в табл. 3.3.

Таблица 3.3. Символы управления форматированием
Параметр Назначение
Флаги
- Выравнивание числа влево. Правая сторона дополняется пробелами. По умолчанию выравнивание вправо.
+ Перед числом выводится знак "+" или "-"
0 Заполнение. Незаполненные позиции дополняются нулями
Ширина
n Ширина поля вывода. Если n позиций недостаточно, то поле вывода расширяется до минимально необходимого. Незаполненные позиции дополняются пробелами
Точность
ничего Точность по умолчанию
m Для типов e, E, f выводить m знаков после десятичной точки
Тип
c При вводе символьный тип char, при выводе один байт.
d Десятичное целое со знаком
i Десятичное целое со знаком
o Восьмеричное целое без знака
u Десятичное целое без знака
x, X Шестнадцатеричное целое без знака, при х используются символы a - f, при Х - A-F
f Значение со знаком вида [-]dddd.dddd
e Значение со знаком вида [-]d.dddd e[+|-]ddd
E Значение со знаком вида [-]d.dddd E[+|-]ddd
g Значение со знаком типа e или f в зависимости от значения и точности
G Значение со знаком типа E или F в зависимости от значения и точности
s Строка символов

В строке вывода могут использоваться некоторые специальные символы, приведённые в табл. 3.4.

Таблица 3.4. Специальные символы
Символ Назначение
\b Сдвиг текущей позиции влево
\n Перевод строки
\r Перевод в начало строки, не переходя на новую строку
\t Горизонтальная табуляция
\’ Символ одинарной кавычки
\" Символ двойной кавычки
\? Символ ?

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

A = fscanf (f, s1, n)

Здесь f — идентификатор файла, который возвращается функцией fopen, s1 — строка форматов вида %[ширина][.точность]тип, s2 — имя переменной, количество считываемых значений.

Функция fscanf работает следующим образом: из файла с идентификатором f считывается в переменную A n значений в соответствии с форматом s1. При чтении числовых значений из текстового файла следует помнить, что два числа считаются разделёнными, если между ними есть хотя бы один пробел, символ табуляции или символ перехода на новую строку.

При считывании данных из текстового файла пользователь может следить, достигнут ли конец файла с помощью функции feof (f) (f — идентификатор файла), которая возвращает единицу, если достигнут конец файла, и ноль — в противном случае.

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

fclose(f)

Здесь f — идентификатор закрываемого файла. С помощью функции fclose('all') можно закрыть сразу все открытые файлы кроме стандартных системных файлов.

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

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

Далее приведена программа решениями задачи с комментариями.

	
N=input(’N=’);% Ввод размеров матрицы.
for i =1:N % Ввод элементов матрицы.
	for j =1:N
			A(i, j)=input(strcat(’A(’, int2str (i), ’,’, int2str(j), ’)=’ ) );
	end
end
% Открыть файл для записи (создать новый пустой файл).
f=fopen(’prim_4_9.txt’, ’wt’);
% Вывод в файл строки ИСХОДНАЯ МАТРИЦА А
% и перевод курсора на новую строку (символ \n).
fprintf(f, ’ИСХОДНАЯ МАТРИЦА А\n’ );
for i =1:N % Цикл для построчной записи элементов матрицы в файл.
	for j =1:N % Цикл для записи в файл i-й строки матрицы.
			fprintf(f, ’%f\t’,A(i, j ) ); % Запись очередного элемента
										% A(i, j ) и символа табуляции в файл.
	end
	fprintf(f, ’\n’); % После записи очередной строки переход к
						% следующей строке файла.
end
for i =1:N % В каждой строке матрицы
	b=A(i, i); % поменять местами элементы расположенные
	A(i, i)=A(i,N+1-i ); % на главной и побочной диагоналях.
	A(i,N+1-i)=b;
end
% Вывод в файл строки МАТРИЦА A после преобразования
% и перевод курсора на новую строку (символ \n).
fprintf(f, ’МАТРИЦА А после преобразования\n’);
for i =1:N % Двойной цикл для вывода матрицы в файл.
	for j =1:N
			fprintf(f, ’%f\t’,A(i, j));
	end
	fprintf(f, ’\n’);
end
fclose(f); % Закрытие файла после записи в него необходимой информации.
Листинг 3.10. Решение к примеру 3.10.

В результате работы программы создан файл prim_3_10.txt, который можно открыть при помощи обычного текстового редактора.

	
ИСХОДНАЯ МАТРИЦА A
1.000000 2.000000 3.000000
4.000000 5.000000 6.000000
7.000000 8.000000 9.000000
МАТРИЦА A после преобразования
3.000000 2.000000 1.000000
4.000000 5.000000 6.000000
9.000000 8.000000 7.000000
Файл prim_3_10.txt

Обратите внимание, что после записи информации в файл этот файл обязательно надо закрывать с помощью функции fclose. Дело в том, что fprintf не обращается непосредственно к диску — он пишет информацию в специальный участок памяти, называемый буфером файла. После того как буфер заполнится, вся информация из него вносится в файл. При вызове функции fclose сначала происходит запись буфера файла на диск, и только потом файл закрывается. Если файл не закрыть, то он автоматически закрывается при завершении работы программы, но при этом пропадает информация, хранимая в буфере файла.

Пример 3.11. Записать матрицу A(N, M) в файл следующим образом. Пусть в первой строке текстового файла хранятся числа N и M, а затем — построчно матрица A.

Листинг 3.11 содержит программу для создания подобного файла.

	
N=input(’N=’); M=input(’M=’); % Ввод размеров матрицы.
for i =1:N % Ввод элементов матрицы.
	for j =1:M
		A(i, j)=input(strcat(’A(’, int2str(i), ’,’, int2str(j), ’)=’ ) );
	end
end
f=fopen(’primer.txt’, ’wt’); % Открыть файл для записи.
fprintf(f, ’%d\t%d\n’,N,M); % Записать в файл N и M, разделив их,
	% символом табуляции после чего перейти на новую строку в файле.
for i =1:N % Цикл для построчной записи элементов матрицы в файл.
	for j =1:M % Цикл для поэлементной записи i -й строки матрицы.
	fprintf(f, ’%g\t’,A( i, j ) ); % Запись очередного элемента A(i, j )
	% и символа табуляции в файл.
	end;
	fprintf(f, ’\n’); % Строка записана, переходим к следующей.
end;
fclose(f); % Закрыть файл.
Листинг 3.11. Запись матрицы в файл (пример 3.11).

После выполнения этой программы будет создан текстовый файл prim_3_11.txt:

	
5  3
1  2  3
4  5  6
7  8  9
0  1  2
3  4  5
Файл prim_3_11.txt

Пример 3.12. Считать информацию из файла prim_3_11.txt в матрицу.

Рассмотрим поэлементное (листинг 3.12) и построчное (листинг 3.13) чтение матрицы из файла. В обоих случаях чтение из текстового файла начинается с чтения значений N и M, которые хранятся в первой строке файла prim_3_11.txt. Затем при построчном чтении организован цикл, в котором считывается одна строка с помощью функции fscanf. При поэлементном чтении организован двойной цикл, в котором функция fscanf считывает значение одного элемента матрицы из файла.

	
f=fopen(’primer.txt’, ’rt’);% Открываем файл для чтения.
N=fscanf(f, ’%d’, 1); % Считываем количество строк в переменную N
M=fscanf(f, ’%d’, 1); % Считываем количество столбцов в переменную M
for i =1:N % Двойной цикл по строкам и столбцам.
	for j =1:M
		A( i, j )=fscanf(f, ’%g’, 1); % Считываем в матрицу один элемент
	end;
end;
fclose(f);% Закрываем файл.
A % Вывод матрицы на экран. Результат работы программы:
A =
1 2 3
4 5 6
7 8 9
0 1 2
3 4 5
Листинг 3.12. Поэлементное чтение матрицы из файла к примеру 3.12
	
f=fopen(’primer.txt’, ’rt’); % Открываем файл для чтения.
N=fscanf(f, ’%d’, 1); % Считываем количество строк в переменную N
M=fscanf(f, ’%d’, 1); % Считываем количество столбцов в переменную M
for i =1:N % Открываем цикл по строкам.
	A(i, :) =fscanf(f, ’%g’,M); % Считываем в i-ю строку из M элементов
end;
fclose(f); % Закрываем файл.
A % Вывод матрицы на экран. Результат работы программы:
A =
1 2 3
4 5 6
7 8 9
0 1 2
3 4 5
Листинг 3.13. Построчное чтение матрицы из файла к примеру 3.12

Пример 3.13. Считать в массив вещественные значения из текстового файла one.txt:

	
1.22  3.45  5.6  7.8
9.1  8.2  9.3  7.41  10
Файл one.txt

Возможно считывание из файла всего массива целиком (листинг 3.14) или поэлементное считывание данных из файла (листинг 3.15).

	
f=fopen(’one.txt’);% Открываем файл для чтения.
x=fscanf(f, ’%f’); % Считываем содержимое файла целиком в массив.
% Сформирован массив x. Результат работы программы:
x =
1.2200
3.4500
5.6000
7.8000
9.1000
8.2000
9.3000
7.4100
10.0000
Листинг 3.14. Считывание данных в массив целиком. Пример 3.13
	
f=fopen(’one.txt’);% Открываем файл для чтения.
i =0; % В переменной i хранится номер элемента массива в который будет
	% осуществляться считывание очередного значения из файла;
	% в начале в i записываем 0, пока в массиве нет элементов.
while ~ feof(f) % Проверяем, если не достигнут конец файла,
	i=i +1; % то увеличиваем i на единицу
	X(i)=fscanf(f, ’%f’, 1); % и считываем очередной i-й элемент
end
X % В массиве X из i элементов хранятся все числа из файла one.txt
% Результат работы программы
X = 1.220 3.450 5.600 7.800 9.100 8.200 9.300 7.4101 0.000
Листинг 3.15. Поэлементное считывание данных. Пример 3.13

Обратите внимание, если данные в файле располагаются в несколько строк, то программы, аналогичные приведённым в листингах 3.12 и 3.13, считывают их как матрицу значений, а программы, приведённые в листингах 3.14 и 3.15 считывают значения из файла в одномерный массив.

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

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

  1. M = dlmread('filename') — чтение чисел из текстового файла filename в матрицу M, числа внутри строки отделяются запятой. В листинге ниже представлен результат чтения данных из файла one.txt (см. пример 3.13).
    	
    >>> H=dlmread(’one.txt’)
    H =
    	1.22000 3.45000 5.60000 7.80000 0.00000
    	9.10000 8.20000 9.30000 7.410001 0.00000
    
    Если в каких-либо строках текстового файла пропущено значение, то недостающий элемент матрицы будет равен нулю.
  2. M = dlmread('filename', delimiter) — чтение чисел из текстового файла filename в матрицу M, числа отделяются символом, храняещмся в delimiter. Например, M = dlmread('ab.txt','\t') —чтение из файла ab.txt чисел в матрицу M, внутри строки числа отделяются табуляцией. В качестве примера рассмотрим файл two.txt, в котором числа внутри строки разделены двоеточием:
    	
    4.3 : 45.78 : 12.90
    23.54 : 0.113 : 78
    Файл two.txt
    
    Ниже представлен результат чтения данных из файла two.txt.
    	
    >>> L=dlmread(’two.txt’, ’:’)
    L =
    4.300004 5.780001 2.90000
    23.5400 0.113007 8.00000
    
  3. M = dlmread('filename', delimiter, R, C ) — чтение чисел из текстового файла filename в матрицу M, числа внутри строки отделяются символом, хранящимся в delimiter, начиная со строки R и столбца C. Строки и столбцы нумеруются с 0. В листинге представлено чтение матрицы из файла two.txt начиная со второй строки и третьего столбца:
    	
    >>> L=dlmread(’two.txt’, ’:’, 1, 2)
    L = 78
    
  4. M = dlmread('filename', delimiter, range) — чтение чисел из текстового файла filename в матрицу M, числа внутри строки отделяются символом, хранящимся в delimiter, range определяет область [row_startcol_startrow_endcol_end], row_start, col_start — левый верхний угол, а row_end, col_end — правый нижний угол области данных, которые считываются из файла. Область range может быть задана в стиле электронных таблиц, например — 'A1 : C3'. В листинге представлено чтение матрицы из файла one.txt:
	
>>> P=dlmread(’one.txt’, ’ ’, [0 0 1 2])
P =
1.2200 3.4500 5.6000
9.1000 8.2000 9.3000
>>> P=dlmread(’one.txt’, ’ ’, ’A1:C2’)
P =
1.2200 3.4500 5.6000
9.1000 8.2000 9.3000

Функция dlmwrite предназначена для записи матрицы в текстовый файл. Существуют три варианта использования функции.

  1. dlmwriter('filename', M) — запись матрицы M в текстовый файл filename, числа внутри строки отделяются запятой.
  2. dlmwriter('filename', M, delimiter) — запись матрицы M в текстовый файл, числа внутри строки отделяются символом, хранящимся в delimiter.
  3. dlmwriter('filename', M, delimiter, R, C) — запись матрицы M,начиная со строки R и столбца C в текстовый файл filename,числа внутри строки отделяются символом, хранящимся в dlmwriter.

Вывести содержимое текстового файла с именем filename на экран можно с помощью функции: type('filename');

Пример вызова функций dlmwrite и type:

	
>>> M=[1 2 3; 4 5 6; 7 8 9];
>>> dlmwrite(’file.txt’,M);
>>> type(’file.txt’)
file.txt is the user-defined function defined from: ./file.txt
1, 2, 3
4, 5, 6
7, 8, 9
Алексей Игнатьев
Алексей Игнатьев

Возможна ли разработка приложения на Octave с GUI?

Евгений Ветчанин
Евгений Ветчанин

Добрый день. Я самостоятельно изучил курс "Введение в Octave" и хочу получить сертификат. Что нужно сднлать для этого? Нужно ли записаться на персональное обучение с тьютором или достаточно перевести деньги?

Иван Мельников
Иван Мельников
Россия
Ольга Замятина
Ольга Замятина
Россия, Калиниград, РГУ им. И. Канта, 2009