Главная Обратная связь

Дисциплины:

Архитектура (936)
Биология (6393)
География (744)
История (25)
Компьютеры (1497)
Кулинария (2184)
Культура (3938)
Литература (5778)
Математика (5918)
Медицина (9278)
Механика (2776)
Образование (13883)
Политика (26404)
Правоведение (321)
Психология (56518)
Религия (1833)
Социология (23400)
Спорт (2350)
Строительство (17942)
Технология (5741)
Транспорт (14634)
Физика (1043)
Философия (440)
Финансы (17336)
Химия (4931)
Экология (6055)
Экономика (9200)
Электроника (7621)


 

 

 

 



Вычисления в интерактивном режиме. 6 часть



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

При вызове функции NumLength не нужно (и нельзя) упаковывать входные числовые вектор-строки в массив ячеек, так как MATLAB делает это сам. Достаточно перечислить их в качестве фактических параметров через запятую:

NumLength( [ 1 2], [3 4] )

ans =

Теперь вызовем функцию NumLength с другим числом параметров:

NumLength( [ 1 2], [3 4], [ 5 6] )

ans =

Функция легко обрабатывает оба этих случая.

Использование массивов ячеек для передачи M-функциям произвольного числа параметров (или для возвращения функцией произвольного числа выходных значений) является единственно возвожным решением проблемы. Существуют ещё и другие случаи, когда обязательно требуется применение массива ячеек. О них будет рассказано в следующей главе. А сейчас ещё упомянем удобный способ заменить список величин, разделённых запятыми, компактным индексным выражением с массивом ячеек.

Таким заменителем является индексное выражение, извлекающее содержимое диапазона ячеек из массива ячеек. Для примера рассмотрим функцию plot(), которая изучалась нами в главе, посвящённой построению графиков функций. Этой функции в качестве параметров передаются массив значений независимой переменной, массив значений зависимой переменной и текстовая строка, управляющая внешним видом графика. Для компактности все эти переменные (массивы) можно упаковать в массив ячеек, например,

F( 1 ) = { 0 : 0.1 : pi };

F( 2 ) = { sin( F{1} ) };

F( 3 ) = { 'bo:' };

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

plot( F{ 1 : 3 } )

так как операция взятия содержимого диапазона ячеек с точки зрения системы MATLAB порождает список величин, разделённых запятыми.

10. Чтение и запись файлов данных. Ранее были рассмотрены MAT-файлы, в которых сохраняются переменные из рабочей области системы MATLAB. Также были рассмотрены M-файлы, хранящие текст M-функций. Теперь рассмотрим файлы произвольного формата, в которых M-функции могут записывать, а затем читать собственные данные.

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

Начнём с числовых векторов и матриц. Работать будем с так называемыми бинарными (не текстовыми) файлами, которые сначала надо открыть с помощью предназначенной для этого функцией fopen системы MATLAB:

fid = fopen( 'имя-файла', 'флаг' )

где имя файла может предваряться полным путём к нему (иначе файл должен располагаться в текущем каталоге MATLABа). Второй параметр этой функции - так называемый флаг открытия файла, говорит о способе дальнейшей работы с файлом:

'rb' - только для чтения

'wb' - только для записи (предыдущее содержимое теряется)

Вторая буква в этих примерах говорит о бинарном характере файлов. Возможен ещё флаг, разрешающий как чтение, так и запись файлов одновременно ( 'r+' ), но мы его здесь использовать не будем.

Функция fopen возвращает числовой идентификатор открытого файла, который надо использовать в качестве параметра для функций чтения и записи в этот файл. Если операция открытия файла не удалась (это возможно как по причине отсутствия файла, так и по причине неправильного указания пути к нему на диске), то функция fopen возвращает -1.

Всегда следует проверять возврат функции fopen:

fid = fopen( 'имя_файла', 'флаг' );

if( fid == -1 )

error( 'File is not opened' )

end

После того, как файл больше не требуется, его следует закрыть функцией fclose:

fclose( fid )

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

fwrite( fid, A, 'precision' )

где fid - файловый идентификатор, возвращаемый функцией fopen; A - вектор или матрица, чьи элементы подлежат записи в файл; строка 'precision' говорит о размере памяти, отводимой под вещественные числа. Это 8 байт или 64 бита, так что строка должна иметь вид 'float64'.

В следующем фрагменте кода создаются вектор-столбец a и матрица B размером 2x3, которые затем записываются в файл с именем 'dataTest.gqw' (здесь расширение имени файла выбрано произвольно так, чтобы не совпасть с известными расширениями):

a = [ 1; 2; 3 ]; B = [ 4 5 6; 7 8 9 ];

fid1 = fopen( 'dataTest.gqw', 'wb' );

fwrite( fid1, a, 'float64' );

fwrite( fid1, B, 'float64' );

fclose( fid1 );

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

fid1 = fopen( 'dataTest.gqw', 'rb' );

[ a , count ] = fread( fid1, [1 3], 'float64' );

[ B , count ] = fread( fid1, [2 3], 'float64' );

fclose( fid1 );

Легко убедиться, что прочитанные значения совпадают с ранее записанными. При этом число count равно числу реально прочитанных вещественных чисел. При чтении вектора a это число будет равно 3, а при чтении матрицы B - будет равно 6.

B =

4 5 6

7 8 9

 

count =

Последний из приведённых нами фрагментов кода страдает рядом практических недостатков, которые ярко высвечивают проблемы, с которыми приходится сталкиваться при работе с файлами (особенно, бинарными). Во-первых, мы лишь для краткости изложения не применяем проверку правильности открытия файла, о которой мы уже говорили выше.

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

Для отслеживания позиции файлового указателя и работы с ним служат функции feof (служит для индикации конца файла), fseek (устанавливает файловый указатель), ftell (позволяет узнать значение текущего файлового указателя), frewind (устанавливает файловый указатель на началдо файла). Все эти функции имеют прозрачный смысл, поэтому мы их подробно не будем рассматривать. О них всегда можно разузнать в справочной системе MATLABа.

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

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

Вот пример такой работы:

str1 = 'Hello'; str2 = 'World!';

fid1 = fopen( 'strTest.gqw', 'wb' );

fwrite( fid1, str1, 'int16' );

fwrite( fid1, str2, 'int16' );

fclose( fid1 );

В результате будет создан файл strTest.gqw, содержащий в бинарном формате содержимое двух строковых переменных. Их можно прочесть с помощью функции fread:

fid1 = fopen( 'strTest.gqw', 'rb' );

[ a , count ] = fread( fid1, 5, 'int16' );

[ b , count ] = fread( fid1, 6, 'int16' );

str1 = char( a' ); str2 = char( b' );

fclose( fid1 );

К прочитанным из файла числовым вектор-столбцам a и b сначала применяется операция транспонирования для перевода их в вектор-строки, а затем осуществляется преобразование к типу char.

Для работы со строковыми данными больше подходят текстовые файлы. Их открывают с флагами 'r' или 'w' (букву b, что означает binary - двоичный, теперь добавлять не надо). Писать и читать строковые переменные в эти файлы удобно с помощью функций fprintf и fscanf. Вот пример записи в файл:

str1 = 'Hello'; str2 = 'World!';

fid1 = fopen( 'strTest2.txt', 'w' );

fprintf( fid1, '%s\r\n%s\r\n', str1, str2 );

fclose( fid1 );

Одним вызовом функции fprintf удаётся записать сразу две строковые (символьные) переменные str1 и str2. Информацию об этом нужно располагать во втором параметре функции fprint в виде символов формата %s, означающих запись строк. Каждый из этих символов нужно завершать парой специальных символов \r\n, означающих "возврат каретки и перевод строки". Таким образом, каждая из этих двух строк при чтении файла любым стандартным текстовым редактором (например, редактором Notepad) будет показана на отдельной строке:

 
 

Текстовые файлы, в отличие от бинарных, можно читать с меньшими предосторожностями и без лишней работы и детальных сведений о записанных значениях строковых переменных (раньше мы, например, указывали длину строк). Теперь, когда мы записали две строковые переменные с их разделением спецсимволами \r\n, мы может читать строки без указания их длины. Для этого следует воспользоваться функцией fgetl (взять новую строку):

fid1 = fopen( 'strTest2.txt', 'r' );

str1 = fgetl( fid1 );

str2 = fgetl( fid1 );

fclose( fid1 );

 
 

Легко убедиться, что прочитанные значения совпадают с ранее записанными в этот текстовый файл:

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



Просмотров 737

Эта страница нарушает авторские права




allrefrs.su - 2025 год. Все права принадлежат их авторам!