Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Текстовые файлы
MatLab предлагает достаточно универсальные способы считывания данных из текстовых файлов и записи данных в требуемом виде в текстовый файл. Рассмотрим сначала оперирование с числовыми данными, представленными матрицами и векторами. Пусть в текстовом файле vec.dat в столбик записаны числа в соответствии с правилами MatLab, т.е. для отделения десятичных знаков используется точка, а для записи числа в экспоненциальном виде применяется символ e. Функция load позволяет занести содержимое файла vec.dat в числовой массив. Имя файла, заключенное в апострофы, указывается во входном аргументе load, а в выходном аргументе возвращается вектор-столбец[1]: » v=load('vec.dat'); Обратная операция — запись значений вектор-столбца в файл — производится при помощи команды save, аргументами которой являются: имя файла, переменная, и дополнительный параметр –ascii, означающий запись в текстовом виде: » v2=v.^2; » save 'vec2.dat' v2 –ascii Если числа в текстовом файле расположены в строку и разделены пробелами, то результатом считывания будет вектор-строка. Верно и обратное, запись значений вектор-строки приведет к занесению их в строку в текстовом файле. Запись матрицы командой save приводит к образованию текстового файла с таблицей чисел. Текстовый файл, в каждой строке которого находится одинаковое количество чисел, отделенных друг от друга пробелами, считывается в двумерный массив функцией load. Команды load и save предназначены только для простейшего ввода-вывода числовых данных. Разберем теперь более сложный случай, когда считываемая или записываемая информация содержит не только числа, но и текст. Работа с текстовыми файлами состоит из трех этапов: 1) открытие файла; 2) считывание или запись данных; 3) закрытие файла. Для открытия файла служит функция fopen, которая вызывается с двумя входными аргументами: именем файла и строкой, задающей способ доступа к файлу. Выходным аргументом fopen является идентификатор файла, т.е. переменная, которая впоследствии используется при любом обращении к файлу. Функция fopen возвращает –1, если при открытии файла возникла ошибка. Существует четыре основных способов открытия файла: 1) f=fopen('myfile.dat', 'rt') — открытие текстового файла myfile.dat только для чтения из него; 2) f=fopen('myfile.dat', 'rt+') — открытие текстового файла myfile.dat для чтения и записи данных; 3) f=fopen('myfile.dat', 'wt') — создание пустого текстового файла myfile.dat только для записи данных; 4) f=fopen('myfile.dat', 'wt+') — создание пустого текстового файла myfile.dat для записи и чтения данных. При использовании двух последних вариантов следует соблюдать осторожность — если файл myfile.dat уже существует, то его содержимое будет уничтожено. После открытия файла появляется возможность считывать из него информацию, или заносить ее в файл. По окончании работы с файлом необходимо закрыть его при помощи fclose(f). Построчное считывание информации из текстового файла производится при помощи функции fgetl. Входным аргументом fgetl является идентификатор файла, а выходным — текущая строка. Каждый вызов fgetl приводит к считыванию одной строки и переводу текущей позиции в файле на начало следующей строки. Команды, приведенные на листинге 9.1, последовательно считывают из файла myfile.dat первые три строки в строковые переменные str1, str2, str3. Листинг 9.1. Считывание трех первых строк из текстового файла f=fopen('myfile.dat', 'rt'); str1=fgetl(f); str2=fgetl(f); str3=fgetl(f); fclose(f); При последовательном считывании рано или поздно будет достигнут конец файла, при этом функция fgetl вернет минус 1. Лучше всего перед считыванием проверять, не является ли текущая позиция в файле последней. Для этого предназначена функция feof, которая вызывается от идентификатора файла и возвращает единицу, если текущая позиция последняя и ноль, в противном случае. Обычно последовательное считывание организуется при помощи цикла while. Листинг 9.2 содержит файл-функцию viewfile, которая считывает строки файла, и выводит их в командное окно. Листинг 9.2. Файл-функция viewfile function viewfile(fname) f=fopen(fname, 'rt'); while feof(f)==0 s=fgetl(f); disp(s) end fclose(f); Вызов viewfile('viewfile.m') приводит к отображению текста самой файл-функции в командном окне. Строки записываются в текстовый файл при помощи функции fprintf, ее первым входным аргументом является идентификатор файла, а вторым — добавляемая строка. Символ \n служит для перевода строки. Если поместить его в конец добавляемой строки, то следующая команда fprintf будет осуществлять вывод в файл с новой строки, а если \n находится в начале, то текущая команда fprintf выведет текст с новой строки. Например, последовательность команд (листинг 9.3) приведет к появлению в файле my.txt текста из двух строк (листинг 9.4). Листинг 9.3. Вывод строк в текстовый файл f=fopen('my.txt', 'wt'); fprintf(f, 'текст '); fprintf(f, 'еще текст\n'); fprintf(f, 'а этот текст с новой строки'); fclose(f); Листинг 9.4. Результат работы операторов листинга 9.3 текст еще текст а этот текст с новой строки Аналогичного результата можно добиться, переместив \n из конца строки второй функции fprintf в начало строки третьей функции fprintf. Аргументом fprintf может быть не только строка, но и строковая переменная. В этом случае для обеспечения вывода с новой строки ее следует сцепить со строкой '\n'. Строка, предназначенная для вывода в текстовый файл, может содержать как текст, так и числа. Часто требуется выделить определенное количество позиций под число и вывести его в экспоненциальном виде или с плавающей точкой и с заданным количеством цифр после десятичной точки. Здесь не обойтись без форматного вывода при помощи fprintf, обращение к которой имеет вид: fprintf(идентификатор файла, 'форматы', список переменных) В списке переменных могут быть как числовые переменные (или числа), так и строковые переменные (или строки). Второй аргумент является строкой специального вида с форматами, в которых будут выводится все элементы из списка. Каждый формат начинается со знака процента. Для вывода строк используется формат s, а для вывода чисел — f (с плавающей точкой) или e (экспоненциальный). Число перед s указывает количество позиций, отводимых под вывод строки. При выводе значений числовых переменных перед f или e ставится два числа, разделенных точкой. Первое из них означает количество позиций, выделяемых под все значение переменной, а второе — количество знаков после десятичной точки. Таким образом, под каждый из элементов списка отводится поле определенной длины, выравнивание в котором по умолчанию производится по правому краю. Для выравнивания по левому краю следует после знака процента поставить знак минус. Ниже приведены варианты вызова fprintf и результаты, незаполненные позиции после вывода (пробелы) обозначены символом ○. fprintf(f, '%6.2f', pi) ○ ○ 3.14 fprintf(f, '%-6.2f', pi) 3.14 ○ ○ fprintf(f, '%14.4e', exp(-5)) ○ ○ ○ 6.7379e-003 fprintf(f, '%-14.4e', exp(-5)) 6.7379e-003 ○ ○ ○ fprintf(f, '%8s', 'текст') ○ ○ ○ текст fprintf(f, '%-8s', 'текст') текст ○ ○ ○ В случае, когда зарезервированного поля не хватает под выводимую строку или число, MatLab автоматически увеличивает длину поля[2], например: fprintf(f, '%5.4e', exp(-5)) 6.7379e-003 При одновременном выводе чисел и текста пробелы могут появляться из-за неполностью заполненных полей, выделенных как под числа, так и под строки. Приведенные ниже операторы и результат их выполнения демонстрируют расположение полей в строке текстового файла. Волнистой линией подчеркнуты поля, выделенные под числа, а прямой — под строки, символ ○ по-прежнему обозначает пробелы. x=0.55; fprintf(f, '%-5s%6.2f%6s%20.8e', 'x=', x, 'y=', exp(x)) x= ○ ○ ○ ○ ○ 0.55 ○ ○ ○ ○ y= ○ ○ ○ ○ ○ 1.73325302e+000 Форматный вывод удобен при формировании файла с таблицей результатов. Предположим, что необходимо записать в файл f.dat таблицу значений функции для заданного числа n значений , отстоящих друг от друга на одинаковое расстояние. Файл с таблицей значений должен иметь такую структуру, как показано на листинге 9.5. Листинг 9.5. Текстовый файл с таблицей значений функции f(0.65)=2.55691256e-001 f(0.75)=3.83421803e-001 f(0.85)=5.42800093e-001 f(0.95)=7.34107493e-001 f(1.05)=9.56334106e-001 Очевидно, что следует организовать цикл от начального значения аргумента до конечного с шагом, соответствующим заданному числу точек, а внутри цикла вызывать fprintf с подходящим списком вывода и форматами. Символ \n, предназначенный для перевода строки, помещается в конец строки с форматами (см. листинг 9.6). Листинг 9.6. Файл-функция tab, выводящая таблицу значений функции function tab(a, b, n) h=(b-a)/(n-1); f=fopen('f.dat', 'wt'); for x=a: h: b fprintf(f, '%2s%4.2f%2s%15.8e\n', 'f(', x, ')=', x^2*sin(x)) end fclose(f); Обратимся теперь к считыванию данных из текстового файла. Функция fscanf осуществляет обратное действие по отношению к fprintf. Каждый вызов fscanf приводит к занесению данных, начинающихся с текущей позиции, в переменную. Тип переменной определяется заданным форматом. В общем случае, обращение к fscanf имеет вид: a=fscanf(идентификатор файла, 'формат', число считываемых элементов) Для считывания строк используется формат %s, для целых чисел — %d, а для вещественных — %g. Предположим, что файл exper.dat содержит текст, приведенный на листинге 9.7. Данные отделены друг от друга пробелами. Требуется считать дату проведения эксперимента (число, месяц и год) в подходящие переменные, а результаты занести в числовые массивы TIME и DAT. Листинг 9.7. Файл с данными exper.dat Результаты экспериментов 10 мая 2002 t= 0.1 0.2 0.3 0.4 0.5 G= 3.02 3.05 2.99 2.84 3.11 Считывание разнородных данных (числа, строки, массивы) требует контроля, который достигается применением форматов. Первые два элемента файла exper.dat являются строками, следовательно можно сразу занести их в одну строковую переменную head. Очевидно, надо указать формат %s и число 2 считываемых элементов[3]. Далее требуется считать целое число 10, строку 'мая' и снова целое число 2002. Обратите внимание, что перед заполнением массива TIME еще придется предусмотреть считывание строки 't='. Теперь все готово для занесения пяти вещественных чисел в вектор-столбец TIME при помощи формата %g. Данные из последней строки файла exper.dat извлекаются аналогичным образом (листинг 9.8). Листинг 9.8. Применение fscanf для считывания данных f=fopen('exper.dat'); head=fscanf(f, '%s', 2) data=fscanf(f, '%d') month=fscanf(f, '%s', 1) year=fscanf(f, '%d') str1=fscanf(f, '%s', 1) TIME=fscanf(f, '%g', 5) str2=fscanf(f, '%s', 1) DATA=fscanf(f, '%g', 5) fclose(f); Информация в текстовом файле может быть представлена в виде таблицы. Для считывания такой информации следует использовать массив структур с подходящим набором полей. Считывание всей информации реализуется в цикле while, в условии которого производится проверка на достижение конца файла при помощи функции feof. Функция fscanf предоставляет возможность считывать числа из текстового файла не только в вектор-столбец, но и массив заданных размеров. Расположение чисел по строкам в файле не имеет значения. Размеры формируемого массива указываются в векторе в третьем входном аргументе fscanf. Рассмотрим считывание числовых данных из файла matr.txt (листинг 9.9). Листинг 9.9. Текстовый файл matr.txt с матрицей 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 0.2 0.4 0.6 0.8 Функция fscanf формирует столбец матрицы, последовательно считывая числа из файла (т. е. построчно). Следовательно, для заполнения матрицы с тремя строками и четырьмя столбцами, необходимо считать данные из файла в массив четыре на три, а затем транспонировать его (листинг 9.10). Листинг 9.10. Считывание матрицы из текстового файла f=fopen('matr.txt'); M=fscanf(f, '%g', [4 3]); M=M' fclose(f) Обратите внимание, что массив может иметь размеры не только 3 на 4. Поскольку данные считываются подряд, то они могут быть занесены и в массив 2 на 6, и 4 на 3 и т. д. Задания для самостоятельной работы Написать файл-функцию для считывания данных из файла в структуру или массив структур с подходящими полями. Варианты 1. Алексеев Сергей 1980 5 4 4 5 3 5 Иванов Константин 1981 3 4 3 4 3 5 Петров Олег 1980 5 5 5 4 4 5
2. 21 марта 2002 0.56 0.58 0.49 0.44 23 марта 2002 0.36 0.32 0.28 0.25 25 марта 2002 1.62 1.68 1.71 1.91
3. 195251 СПб Политехническая 29 195256 СПб Науки 49 195256 СПб Науки 24
4. Результаты наблюдений Time= 0.0 0.1 0.2 0.3 0.4 0.5 0.6 Mass= 2.1 2.3 2.3 1.9 1.8 2.4 0.8 0.7 0.5 1.1 3.2 0.3
5. Алексеев Иван 121-22-04 Сидоров Николай 101-21-99 Тимофеев Сергей 570-00-03 (номера телефонов, должны быть записаны в поля структур как целые числа). Задания для самостоятельной работы Считать матрицы и вектора из файла в подходящие по размеру массивы. Обратите внимание, что в файлах содержится рядом две или три матрицы или вектора, их следует занести в разные массивы. Варианты 1. 0.1 0.2 0.3 9.91 1.9 0.4 0.1 8.01 4.7 5.1 3.9 7.16
2. 1.399 2.001 9.921 3.21 0.12 0.129 1.865 8.341 9.33 8.01 9.136 8.401 7.133 3.12 3.22
3. 1 2 3 4 99 80 5 6 7 8 33 21 15 90
4. 10 20 40 50 12 19 21 32 44 -1 -2 -3 -4 32
5. 1 2 3 4 100 6 7 8 9 0.1 0.2 0.3 0.4 200 0.5 0.6 0.7 0.8 300
[1] Файл с данными должен находится в текущем каталоге MatLab, иначе требуется указать полное имя файла. [2] Лучше избегать такие ситуации и заранее рассчитывать длину поля вывода, иначе, например, при выводе таблицы может нарушиться структура данных в файле. [3] Заметьте, что слова заносятся в строковую переменную без пробела между ними. Для получения строки со словами, разделенными пробелом, необходимо считать их по отдельности в разные строковые переменные и сцепить их.
|