Matlab的各種資料讀取、檔案讀寫等操作彙總
轉載 2015年03月11日 16:10:04
- 标簽:
- matlab
- 19019
MATLAB提供了多種方式從磁盤讀入檔案或将資料輸入到工作空間,即讀取資料,又叫導入資料;将工作空間的變量存儲到磁盤檔案中稱為存寫資料,又叫導出資料。至于選擇哪種機制,則根據下面兩個因素決定:
● 使用者所執行的操作是導入資料還是導出資料;
● 資料的格式為文本格式、二進制格式還是如HDF之類的标準格式。
将資料導入MATLAB中最容易的方法就是使用導入資料模闆(Import Wizard),使用該模闆時不需要知道資料的格式,隻需指定包含這些資料的檔案,然後導入模闆會自動處理檔案内容。本章重點内容如下:
● 檔案的打開和關閉
● 文本檔案的讀取
● 存寫ASCII資料
● 二進制資料的讀取
● 二進制資料的存寫
● 使用I/O檔案函數進行資料讀寫
● MAT 檔案的讀寫
2.1 檔案的打開和關閉
2.1.1 檔案的打開
無論是要讀寫ASCII碼檔案還是二進制檔案,都必須先用fopen函數将其打開,在預設情況下,fopen以二進制格式打開檔案,它的使用文法如下:
fopen ('filename', 'mode')
其中filename表示要讀寫的檔案名稱,mode則表示要對檔案進行的處理方式,如下:
rt:以隻讀方式(Reading)打開檔案
wt:以隻寫方式(Writing)打開檔案
at:以追加方式(Appending)打開檔案,新内容将從原檔案後面續寫
r+t:以同時讀寫方式打開檔案
w+t:以同時讀寫建立檔案,原檔案内容被清除
a+t:以同時讀和追加(Reading and Appdending)方式,原檔案内容被保留,新内容将從原檔案的後面開始
At:以讀寫方式打開或建立檔案,适用于對錄音帶媒體檔案的操作
Wt:以寫入方式打開或建立檔案,原檔案内容被清除,适用于錄音帶媒體檔案的操作
fopen函數有兩個傳回值,一個是傳回一個檔案标志(file Identifier),它會作為參數被傳入其他對檔案進行讀寫操作的指令,通常是一個非負的整數,可用此辨別來對此檔案進行各種處理。如果傳回的檔案辨別是–1,則代表fopen無法打開檔案,其原因可能是檔案不存在,或是使用者無法打開此檔案權限。另一個傳回值就是message,用于傳回無法打開檔案的原因。為了安全起見,最好在每次使用fopen函數時,都測試其傳回值是否為有效值。下面以腳本m檔案為例來聲明檔案的打開。
例2-1 %exam1.m
[f,message]=fopen('fileexam1', 'r')
if f==-1
disp (message); %顯示錯誤資訊
end
若檔案fileexam1不存在,則顯示如下資訊。
Cannot open file.existence?permissions?memory?...
例2-2 %exam2.m
[f,message]=fopen('fileexam2', 'r');
if f==-1
disp (message); %顯示錯誤資訊
else
disp(f);
end
若檔案fileexam2存在,則傳回f值。
2.1.2 檔案的關閉
一旦完成檔案的讀寫,最好關閉檔案,以便對其進行其他操作。這時就可以使用fclose函數來關閉檔案,其适用文法如下:fclose(f)。
其中f為打開檔案的标志,若fclose函數傳回值為0,則表示成功關閉f标志的檔案;若傳回值為–1,則表示無法成功關閉該檔案。一般來說,在完成對檔案的讀寫操作後就應關閉它,以免造成系統資源浪費。此外,需注意的是,打開和關閉檔案都比較耗時,是以為了提高程式執行效率,最好不要在循環體内使用檔案。
若要一次關閉打開的所有檔案,可以使用下面的指令:fclose all
2.2 文本資料
雖然MATLAB自帶的MAT檔案為二進制檔案,但為了便于和外部程式進行交換以及友善檢視檔案中的資料,也常常采用文本資料格式與外界進行資料交換。在文本格式中,資料采用ASCII碼格式,可以表示字母和數字字元。ASCII文本資料可以在文本編輯器中檢視和編輯。MATLAB提供多種函數能夠進行檔案讀寫,這些函數都是MATLAB的一部分,不需要額外的工具箱支援。
2.2.1 從文本檔案中讀取資料
1.使用導入模闆來讀取資料
使用導入模闆來讀取資料,需按以下步驟進行:
(1) 選擇File→Import Data選項,然後彈出一個檔案選擇對話框;也可以使用uiimport函數來打開導入資料模闆。
(2) 在檔案選擇對話框中選擇想導入資料的文本檔案,然後單擊Open按鈕,導入資料模闆就會打開該檔案并準備處理其内容。
(3) 指定用于分開單個資料的字元,該字元稱為分隔符或列分隔符。在多數情況下可以用導入模闆來設定分隔符。
(4) 選擇要導入的變量。在預設情況下,導入模闆将所有的數值資料放在一個變量中,而将文本資料放在其他變量中。
(5) 單擊Finish按鈕完成資料的導入。
當使用導入模闆來打開一個文本檔案時,在導入模闆對話框的預覽區僅顯示原始資料的一部分,通過它,使用者可以驗證該檔案中的資料是否為所期望的。導入模闆也根據檔案中的資料分隔符來對導入的資料進行預處理。在導入模闆中打開工作區中的grade.txt檔案。
english math physic
joe 80 90 60
susan 78 98 88
rob 67 90 89
圖2-1 将資料通過模闆導入
在圖2-1中,導入模闆已辨認space字元,把它作為檔案中資料的分隔符,并建立了兩個變量:data(包含檔案中所有數值資料)和textdata(包含檔案中所有文本資料)。
當導入模闆正确導入檔案中的資料後,就會顯示它所建立的變量。要選擇一個變量來導入資料,可單擊它名稱後面的複選框。在預設情況下,所有變量都會被選中。在導入對話框的右面顯示了導入模闆建立的變量内容。要檢視其他變量,隻需要單擊該名稱。在選擇好要導入的變量後,單擊Next按鈕,如圖2-2所示。
圖2-2 使用模闆檢視各變量資料
在預設情況下,導入模闆将檔案中所有的數值資料放在一個變量中;若檔案包含文本資料,則模闆将它們放在另外一個變量中;若檔案包含行或列,模闆也将它們作為各自獨立的變量分别稱為行頭和列頭。
當所有導入模闆建立好資料後,使用whos指令可以檢視工作空間的變量。
>> whos
Name Size Bytes Class Attributes
data 3x3 72 double
textdata 4x1 314 cell
2. 使用函數來讀取文本資料
若要在指令行或在一個 M 檔案中讀取資料,必須使用 MATLAB 資料函數,函數的選擇則是依據文本檔案中資料的格式。而且文本資料格式在行和列上必須采取一緻的模式,并使用文本字元來分隔各個資料項,稱該字元為分隔符或列分隔符。分隔符可以是space、comma、semicolon、ab或其他字元,單個的資料可以是字母、數值字元或它們的混合形式。
文本檔案也可以包含稱之為頭行的一行或多行文本,或可以使用文本頭來标志各列或各行。在了解要輸入資料的格式之後,便可以使用 MATLAB 函數來讀取資料了。若對 MATLAB 函數不熟悉,可從表2-2中了解幾個讀取函數的一些使用特征。
表2-2 讀取函數的比較
函 數 |數 據 類 型 |分 隔 符 返 回 值
csvread |數值資料|僅cooma|1
dlmread|數值資料|任何字元|1
fscanf|字母和數值|任何字元|1
load|數值資料|僅space|1
textread|字母和數值|任何字元|多傳回值
3. 讀取數值文本資料
若使用者的資料檔案隻包含數值資料,則可以使用許多MATLAB函數,這取決于這些資料采用的分隔符。若資料為矩形形狀,也就是說,每行有同樣數目的元素,這時可以使用最簡單的指令load(load也能用于導入MAT檔案,該檔案為用于存儲工作空間變量的二進制檔案,如果檔案名字尾是.dat,則MATLAB會以MAT檔案格式進行讀取)。
例如,檔案my_data.txt包含了兩行資料,各資料之間由space字元隔開。
當使用load時,它将讀取資料并在工作空間中建立一個與該檔案同名的變量,但不包括擴充名。
>>load my_data.txt;
調用whos指令檢視工作空間的變量。
>> whos
Name Size Bytes Class Attributes
data 3x3 72 double
my_data 3x4 96 double
textdata 4x1 314 cell
此時可以檢視與該檔案同名的變量的值
>> my_data
my_data =
0.3242 0.4324 0.3455 0.6754
0.4566 0.9368 0.9892 0.9274
0.4658 0.2832 0.9373 0.8233
若想将工作空間的變量以該檔案名命名,則可以使用函數形式的load,下面的語句将檔案導入工作空間并賦給變量A
A=load('my_data.txt');
4. 讀取有分隔符的ASCII資料檔案
如果資料檔案不使用空格符而是使用逗号或是其他符号作為分隔符,使用者可以選擇多個可用的導入資料函數。最簡單的便是使用函數dlmread。
舉個例子來說,一個名為lcode.dat的資料檔案,資料内容由逗号分隔。
0.3445,0.8433,0.7865
0.7562,0.4233,0
要把該檔案的全部内容讀入陣列A,隻須輸入如下指令:
>> A=dlmread('lcode.dat',',')
即可以把資料檔案中使用的分隔符作為函數dlmread的第二個參數。
注意:
即使每行的最後一個資料後面不是逗号,dlmread函數仍能正确讀取資料,因為dlmread忽略了資料之間的空格符。是以,即使資料為如下格式,前面的dlmread指令仍能正常工作。
A =
0.3445 0.8433 0.7865
0.7562 0.4233 0
另外需要注意的是,分隔符隻能選取單個字元,不能用字元串來作為分隔符。
5. 使用文本頭讀取數值資料
要讀取一個包含文本頭的ASCII碼資料檔案,可以使用textread函數,并指定頭行參數。調用函數textread 同樣非常簡單,同時對檔案讀取的格式處理能力更強,函數接收一組預先定義好的參數,由這些參數來控制變量的不同方面。Textread既能處理有固定格式的檔案,也可以處理無格式的檔案,還可以對檔案中每行資料按列逐個讀取。
textread函數常見的調用方法有如下幾種:
[A,B,C...]=textread('filename', 'format')
[A,B,C...]=textread('filename', 'format',N)
例如檔案my_data.txt包含了如下檔案内容,有一行文本頭,且格式化的數值資料。
num1 num2 num3 num4
0.3242 0.4324 0.3455 0.6754
0.4566 0.9368 0.9892 0.9274
0.4658 0.2832 0.9373 0.8233
因為有檔案頭,要使用如下textread指令來讀取檔案中的資料。
>> [num1 num2 num3 num4]=textread('my_data.txt','%f %f %f %f','headerlines',1)
執行結果如下:
num1 =
0.3242
0.4566
0.4658
num2 =
0.4324
0.9368
0.2832
num3 =
0.3455
0.9892
0.9373
num4 =
0.6754
0.9274
0.8233
6. 讀取字母數值混合的資料
若資料檔案中包含了字母和數值混合的ASCII碼資料,也可以使用函數textread來讀取資料。由上一小節知道,函數textread可以傳回多個輸出變量,實際上使用者還可以通過參數指定每個變量的資料類型。
例如要把檔案my_exam.dat的全部内容讀入工作空間,需要在textread行數的輸入參數中指定資料檔案的名稱和格式。
檔案my_exam.dat包含的混合的字母和數值如下:
Joe gradeA 4.9 pass
susan gradeD 2.0 fail
如果想把4列資料全部讀取出放在4個變量中,則使用如下指令:
>> [name gra grades answer]=textread('my_exam.dat','%s %s %f %s')
在這裡要注意指令中格式字元串的定義,對于格式字元串中定義的每種變換,必須指定一個單獨的輸出變量,textread 函數按格式字元串中指定的格式處理檔案中的某個資料項,并把值放在輸出變量中。輸出變量的數目必須和格式字元串中指定的變換數目項比對,在該例中,函數按格式字元串來讀取檔案my_exam.dat的每一行,直到檔案讀完,該指令的執行結果是:
name =
'Joe'
'susan'
gra =
'gradeA'
'gradeD'
grades =
4.9000
2.0000
answer =
'pass'
'fail
另外,textread函數可以有選擇地讀取資料,比如我們不需要取出中間幾列資料,隻取出第一列和最後一列資料,則可以使用指令:
>> [name answer]=textread('my_exam.dat','%s %*s %*f %s')
name =
'Joe'
'susan'
answer=
'pass'
'fail'
若檔案采用的分隔符不是空格,則必須使用函數textread ,将該分隔符作為它的參數。例如,若檔案my_exam.dat 使用分号作為分隔符,則讀入該檔案需使用如下指令:
[name gra grades ans]=textread('my_exam.dat','%s %s %f %s', 'delimiter', '; ')
2.2.2 存寫ASCII碼資料
本小節介紹如何使用MATLAB函數按幾種通用的ASCII碼格式來存寫資料,即如何使用這些函數來把一個MATLAB數值矩陣寫入到一個文本檔案中,其中該矩陣的列和行使用空格符來分隔。使用者采用什麼函數取決于所要存寫資料的資料量和資料格式。
常用的兩種ASCII碼資料格式如下:
● 采用空格符分隔;
● 采用分号分隔。
MATLAB的存寫資料函數如表2-3所示。
表2-3 資料存寫函數
函 數 名 稱|适 用 數 據|分 隔 符
csvwrite|數值資料|逗号
diary|數值資料或單元陣列|空格
dlmwrite|數值資料|任何字元
fprintf|字母和數值資料|任何字元
save|數值資料|制表符或空格符
1. 存寫有分隔符的ASCII碼資料檔案
若要将目前的MATLAB工作空間的一個或多個變量寫到一個有分隔符的ASCII碼檔案中,可以使用save指令或dlmwrite函數。在預設情況下,save指令是以 MAT 格式存寫資料的,這部分内容我們在後面詳細介紹,本小節主要介紹 save指令通過ASCII碼限定符以文本方式存寫資料。而dlmwrite函數則可以提供更大的靈活性,它允許使用者把任何字元指定為分隔符,也可以通過指定一個值域存寫一個陣列的子陣列。
>> clear all;
>> x=rand(2,3);
>> save my_test1.dat x -ascii;
該指令将變量x中的資料存寫到my_test1.dat檔案中。通過文本編輯器,我們可以檢視該檔案的内容:
9.2181297e-001 1.7626614e-001 9.3546970e-001
7.3820725e-001 4.0570621e-001 9.1690444e-001
我們也可以将指令中的檔案名和變量名省略,那樣的話,指令的執行結果則是把目前 MATLAB工作空間中的所有變量儲存到matlab.mat檔案中。需要指明的是這時的檔案雖然字尾名為.mat,但檔案内容仍然是以文本方式儲存的。
在預設情況下,save指令使用空格作為分隔符,但使用者可以通過指定-tabs限定符來使用制表符而不是空格符作為分隔符。當使用save指令把一個字元陣列寫入ASCII檔案時,将ASCII碼寫入檔案也就等于把字元寫入檔案。
若要以ASCII碼形式存寫一個陣列,并指定檔案使用的分隔符,需要使用dlmwrite函數,比如重新指定分号作為分隔符,把變量x存到檔案 my_test2.dat 檔案中,檢視其結果:
0.92181;0.17627;0.93547
0.73821;0.40571;0.9169
在預設情況下,dlmwrite函數用逗号或空格作為分隔符,或者是指定空的引号,即無分隔符。
2. 使用diary指令來存寫資料
較小的數值陣列或單元陣列的存寫可以使用diary指令,例如,在工作空間中有一個陣列A: A=[1 2 3 4 5; 6 7 8 9 10]
在指令提示符下執行如下指令:diary my_test3.dat,就可以建立my_test3.dat檔案。接下來顯示要存寫的陣列A:
A =
1 2 3 4 5
6 7 8 9 10
然後執行關閉diary指令:diary off。
這時,在文本編輯器中打開my_test3.dat檔案,會發現diary指令建立的檔案記錄了在MATLAB會話期間的所有指令。可以通過編輯,删去無關的文本。
2.3 二進制資料
2.3.1 二進制資料的讀取
本小節将介紹怎樣将一般格式下的二進制資料檔案讀取到工作空間中。讀取二進制資料常用的方法有兩種,一是使用導入模闆來導入,二是使用二進制資料導入函數來讀取。
1. 使用導入模闆讀取二進制資料
要使用導入模闆來讀取二進制資料,需按以下步驟進行:
(1) 選擇File→Import Data選項,彈出一個檔案選擇對話框;也可以使用uiimport函數來打開導入資料模闆。
(2) 在檔案選擇對話框中選擇想導入資料的二進制資料檔案,然後單擊Open按鈕,導入資料模闆就會打開該檔案并準備處理其内容。
(3) 選擇要導入的變量。在預設情況下,導入模闆将要建立的變量取決于檔案中的資料類型。
(4) 單擊Finish按鈕完成資料的導入。
這個過程和使用導入模闆讀取文本檔案是基本一緻的,這裡就不再舉例了。
2. 使用導入函數讀取二進制資料
若要從指令行或一個 M 檔案中讀取二進制資料,就必須使用 MATLAB 導入函數,函數的選擇取決于檔案中資料的格式,這些函數如表2-4所示。
表2-4 導入二進制資料函數
函 數 名 稱|讀取檔案的擴充名|數 據 格 式
load|.mat|讀取MATLAB下的MAT資料格式的資料
aviread|.avi|讀取AVI格式的音頻視訊資料
cdfread|.cdf|讀取CDF格式的資料
hdf|.hdf|讀取HDF格式的資料
imread|.bmp .cur .gif .hdf .ico .jpg .pbm .pgm .png .pnm .ppm .pcx .tif .xwd .ras|讀取各種格式的圖形資料
wavread|.wav|讀取 Windows 系統的聲音檔案
xlsread|.xls|讀取 Excel 電子表格資料
2.3.2 二進制資料的存寫
要以一種标準二進制格式來存寫二進制資料,可以使用 MATLAB 提供的高端函數,函數的選擇取決于要存寫資料的類型,這些函數如表2-5所示。
表2-5 導出二進制資料函數
函 數 名 稱|讀取檔案的擴充名|數 據 格 式
save|.mat|存寫MATLAB下的MAT資料格式的資料
avifile|.avi|存寫AVI格式的音頻視訊資料
cdfwrite|.cdf|存寫CDF格式的資料
hdf|.hdf|存寫HDF格式的資料
imwrite|.bmp .cur .gif .hdf .ico .jpg .pbm .pgm .png .pnm .ppm .pcx .tif .xwd .ras|存寫各種格式的圖形資料
wavwrite|.wav|存寫 Windows 系統的聲音檔案
xlswrite|.xls|存寫 Excel 電子表格資料
在MATLAB中可以将一系列的圖像儲存為電影,這樣使用電影播放函數就可以進行回放,儲存方法可以同儲存其他MATLAB工作空間變量一樣,通過采用MAT檔案格式儲存。但是若要浏覽該電影,必須在MATLAB環境下。在以某種格式存寫一系列的MATLAB圖像時,不需要在MATLBA 環境下進行預覽,通常采用的格式為AVI格式。AVI是一種檔案格式,在PC 機上的Windows系統或UNIX作業系統下可以進行動畫或視訊的播放。
若要以AVI格式來存寫MATLAB圖像,步驟如下:
(1) 用avifile函數建立一個AVI檔案。
(2) 用addframe函數來捕捉圖像并儲存到AVI 檔案中。
(3) 使用close函數關閉AVI檔案。
注意:
若要将一個已經存在的MATLAB電影檔案轉換為AVI檔案,需使用函數movie2avi。函數原型為:
movie2avi(mov,filename)
movie2avi(mov,filename,param,value,param,value...)
2.4 使用檔案I/O函數
前面介紹的都是MATLAB中的一些進階函數,除此之外MATLAB還包含了一組低端的檔案I/O函數,如前面介紹的所有檔案的打開和關閉函數:fopen函數和fclose函數。這些函數是建立在ANSI标準C庫中的I/O函數。若使用者對C語言熟悉的話,那麼也肯定熟悉這些函數。比如,MATLAB 檔案I/O函數使用和C語言同樣的程式設計模式等。要讀寫這些資料,需進行以下幾步:
(1) 使用fopen函數打開檔案。fopen函數将會傳回一個檔案标志,通過它,就可以使用其他所有的低端檔案I/O函數。
(2) 對檔案進行操作,如:讀寫二進制資料、格式化讀寫文本資料等。
(3) 使用fclose函數來關閉檔案。
2.4.1 二進制資料的讀取
使用fread函數可從檔案中讀取二進制資料,它将每個位元組看成整數,并将結果以矩陣形式傳回。對于讀取二進制檔案,fread必須制定正确的資料精度。fread的基本調用方法是:A=fread(fid)
其中fid是一個整數型變量,是通過調用fopen函數獲得的,表示要讀取的檔案辨別符,輸出變量A為矩陣,用于儲存從檔案中讀取的資料。
例如檔案test.txt的内容如下:
test it
用fread函數讀取該檔案,輸入如下指令:
>> f=fopen('test.txt','r');
>> answer=fread(f)
answer =
116
101
115
116
32
105
116
輸出變量的内容是檔案資料的ASCII碼值,若要驗證讀入的資料是否正确,通過下面的指令可以驗證。
>> disp(char(ans1'))
test it
fread函數的第二個輸入參數可以控制傳回矩陣的大小,例如:
>> f=fopen('test.txt','r');
>> answer=fread(f,2)
answer =
116
101
也可以把傳回矩陣定義為指定的矩陣格式,例如
>> f=fopen('test.txt','r');
>> an=fread(f,[2 3])
answer =
116 115 32
101 116 105
使用fread函數的第三個輸入變量,可以控制fread将二進制資料轉成MATLAB 矩陣用的精度,包括一次讀取的位數(Number of Bits)和這些位數所代表的資料類型。常用的精确度類型有下列幾種,如表2-6所示。
表2-6 常見的精确度類型
數 據 類 型|說 明|
char|帶符号的字元(通常是8h16)
uchar|無符号的字元(通常是8bits)
short|短整數(通常是16bits)
long|長整數(通常是16bits)
float|單精度浮點數(通常是32bits)
double|雙精度浮點數(通常是64bis)
2.4.2 二進制資料的寫入
使用fwrite函數可将矩陣按所指定的二進制格式寫入檔案,并傳回成功寫入檔案的大小。函數的調用方式如下:
count=fwrite(fid,A,precision)
其中,count用來傳回寫入檔案資料的大小,f參數同樣是通過fopen函數獲得的整數型變量,表示檔案辨別符,A表示要寫入的資料矩陣,第三個參數precision同二進制讀取函數的參數一樣,表示資料的寫入格式。
在下例中fwrite産生一個大小為100位元組的二進制檔案,它包含了一個5×5階魔方矩陣,共25個元素,每個元素占用4個位元組。
f=fopen('magic5.bin', 'w');
fwrite(f,magic(5), 'int32');
fclose(f)
二進制檔案在不同的計算機架構上可能存儲方式不同,是以二進制檔案存在相容性問題,而文本檔案則不存在這種相容性問題。不同的存儲方式導緻在不同架構上儲存的二進制檔案在另外的平台上無法讀取,這主要是因為多位元組資料類型在計算機硬體上的存儲順序不同。在MATLAB中,無論計算機上的資料存儲順序是哪一種,都可以讀寫二進制檔案,但要正确地調用fopen函數打開檔案。
2.4.3 格式化讀取ASCII碼資料
fscanf函數與C語言中的fscanf在結構、含義和使用上都很相似,即能夠從一個有格式的檔案中讀入資料,并将它賦給一個或多個變量。兩個函數都采用同一組格式指定符來控制輸入資料的格式,fscanf的格式指定符由字元%開頭,常用格式如表2-7所示。
表2-7 常見的用于輸入的格式轉換符
格式轉換符|意 義
%c|讀取字元型變量,也可以指定多個字元,'%3c'
%s|讀取字元串變量
%d|讀取整數型變量
%f|讀取浮點數
%g|讀取雙精度浮點數
例如,我們仍然讀取my_test.dat檔案中的資料,其資料内容是:
4.5646767e-001 8.2140716e-001 6.1543235e-001
1.8503643e-002 4.4470336e-001 7.9193704e-001
通過下面這段代碼,将該檔案中的資料讀取到列向量T中。
>> f=fopen('my_test.dat','r');
>> T=fscanf(f,'%g');
>> fclose(f)
也可以通過以下代碼段把檔案資料讀取到一個3×2矩陣A中。
>> f=fopen('my_test.dat','r');
>> A=fscanf(f,'%g',[3 2]);
>> fclose(f)
執行後結果如下,這時候A矩陣恰好是檔案中資料矩陣的轉置。
>> A
A =
0.4565 0.0185
0.8214 0.4447
0.6154 0.7919
2.4.4 格式化寫入文本資料
fprintf将會把資料轉換為字元串,并将它們輸出到螢幕或檔案中。一個格式控制字元串包含轉換指定符和可選的文本字元,通過它們來指定輸出格式。轉換指定符用于控制陣列元素的輸出。
當fprint函數做标準輸出,也就是運作結果顯示在螢幕上的時候,它的功能和disp函數相類似,差別僅在于fprint可以輸出特定格式的文本資料。
比如,建立一個2×2的魔方矩陣,然後打開一檔案,寫入資料。
>> clear all;
>> x=magic(2);
>> fid=fopen('exam4.txt','w');
>> fprintf(fid,'%4.2f %8.4f\n',x);
>> fclose(fid);
執行這段程式段之後,我們可以檢驗一下執行結果:
>> x
x =
1 3
4 2
>> type exam4.txt
1.00 4.0000
3.00 2.0000
可以看出,fprintf函數在列印顯示矩陣資料時,資料轉換規則是可以按列方式循環作用于矩陣的各個元素的,這個例子中顯示出來的結果就好像原矩陣的轉置,而且分别按資料轉換規則顯示。
2.4.5 控制檔案位置指針
每一次打開檔案時,MATLAB就會保持一個檔案位置指針(File Position Indicator),由它決定下一次進行資料讀取或寫入的位置。控制此指針的函數如表2-8所示。
表2-8 控制位置指針的函數
函 數 名 稱|功 能 說 明
fseek|設定指針位置
ftell|獲得指針位置
frewind|重設指針到檔案起始位置
feof|測試指針是否在檔案結束位置
fseek 函數用于指定檔案指針的位置,調用方式如下:status=fseek(fid,offset,origin)
fid是指定的檔案辨別符。offset為整數型變量,表示相對于指定位置需要的偏移位元組數,正數表示向檔案末尾偏移,負數表示向檔案開頭偏移。Origin可以是特定字元串,也可以是整數,表示檔案中的參考位置。參考位置的參數說明如表2-9所示。
表2-9 參考位置參數的說明
參考位置(origin)|說 明
'bof '或者 -1|檔案開頭
'cof '或者 0|檔案中目前位置
'eof '或者 1|檔案末尾
ftell 函數用來獲得目前檔案指針的位置,調用方式如下:position=ftell(fid)
fid是指定的檔案辨別符。Position為傳回值,表示目前指針的位置。position是以相對于檔案開頭的位元組數來表示的。如果傳回值為–1,表示未能成功調用。這是可以通過調用feeeor(fid)的具體的錯誤資訊。
frewind 函數用來把檔案指針重新複位到檔案開頭。調用方式如下:
frewind(fid)
其中fid為指定的檔案辨別符,其作用和fseek(fid,0,-1)是等效的。
feof 函數用來判斷是否到達檔案末尾。調用方式如下:
eofstat=feof(fid)
其中fid為指定的檔案辨別符。eofstat是傳回值,當到達檔案末尾時,eofstat為1;否則為0。比如我們仍然對檔案my_test.dat執行以下指令,然後測試檔案指針位置
>> f=fopen('my_test.dat','r');
>> A=fscanf(f,'%g',[3 2])
A =
0.4565 0.0185
0.8214 0.4447
0.6154 0.7919
>>feof(f)
ans=
在本例中,檔案指針指向最後一個資料,而不是檔案末尾,是以傳回值是0,而不是1,但是若執行以下指令:
>> f=fopen('my_test.dat','r');
>> A=fscanf(f,'%g',[4 2])
A =
0.4565 0.4447
0.8214 0.7919
0.6154 0
0.0185 0
>>feof(f)
ans=
1
在my_data.dat檔案中隻包含6個數字,是以feof函數傳回值為1。若要重新設定指針到起始位置,就可以直接使用frewind函數。
2.5 MAT 文 件
MAT檔案是MATLAB使用的一種特有的二進制資料檔案。MAT檔案可以包含一個或者多個MATLAB 變量。MATLAB通常采用MAT檔案把工作空間的變量存儲在磁盤裡,在MAT檔案中不僅儲存各變量資料本身,而且同時儲存變量名以及資料類型等。是以在MATLAB中載入某個MAT檔案後,可以在目前MATLAB工作空間完全再現當初儲存該MAT 檔案時的那些變量。這是其他檔案格式所不能的。同樣,使用者也可以使用MAT檔案從MATLAB環境中導出資料。MAT檔案提供了一種更簡便的機制在不同操作平台之間移動MATLAB資料。
2.5.1 在MATLAB中讀寫MAT檔案
在MATLAB環境中,通常使用load和save兩個指令進行 MAT 檔案的讀和寫。在預設情況下,這兩個指令以 MAT 檔案格式處理檔案,但是也可以用-ascii參數選項來強制用檔案方式處理檔案。關于這點已經在本章介紹過了,這裡主要介紹如何讀寫MAT檔案。
1. load 函數的使用
load函數可以從MAT檔案中讀取資料,例如要讀取mymat.dat檔案,可以直接執行指令load mymat.dat,因為給出要讀取的檔案的字尾名是MAT,是以指令則以MAT檔案格式讀取資料,否則将以文本檔案讀取資料。指令中的檔案名可以包含單引号,也可以不包含,也就是說該函數也可以這樣調用:load 'mymat.mat' 。
load 函數還可以指定隻讀取檔案中的某幾個變量,隻需在檔案名之後列出想要讀取的變量的變量名就可以了,變量名也可以使用通配符。
比如指令load mymat.mat y*,執行結果就是将檔案中所有以y開頭的變量讀取出來。
load還有一種函數形式的調用方式。這種調用方式就要求檔案名必須是字元串,比如要導入mymat.mat檔案,那麼函數形式的調用必須是s = load('mymat.mat')。
2. save函數的使用
save 函數的功能是把目前MATLAB工作空間的一個或多個變量存寫到外部檔案。在預設情況下,save 函數以MAT格式存寫資料。若在指令中直接調用該函數,不帶任何參數,執行結果是把MATLAB工作空間的所有變量儲存到系統預設的matlab.mat檔案中。當然,帶上檔案名參數,就可以将目前工作空間中的所有變量存寫在指定的 MAT檔案中。
如果使用者需要儲存指定的某幾個變量,隻需在檔案名參數後,列出要儲存的檔案名即可。比如,指令save mymat.mat x,y,z執行後的結果就是将目前工作空間中的變量 x,y,z儲存到mymat.mat檔案中,要求x,y,z是目前工作空間中已經存在的變量。
2.5.2 在普通的C/C++程式中讀寫MAT檔案
1.使用MATLAB 提供的MAT 檔案接口函數
在C/C++程式中有兩種方式可以讀取MAT檔案資料。一種是利用MATLAB提供的有關MAT檔案的程式設計接口函數。MATLAB的庫函數中包含了MAT檔案接口函數庫,其中有各種對MAT檔案進行讀寫的函數,都是以mat開頭的函數。如表2-10所示。
表2-10 C語言中的MAT檔案讀寫函數
MAT 函 數|功 能
matOpen|打開 MAT 檔案
matClose|關閉 MAT 檔案
matGetDir|從 MAT 檔案中獲得 MATLAB 陣列的清單
matGetFp|獲得一個指向MAT 檔案的ANSI C 檔案指針
matGetVariable|從MAT檔案中讀取MATLAB陣列
matPutVariable|寫MATLAB陣列到MAT檔案
matGetNextVariable|從MAT檔案中讀取下一個MATLAB陣列
matDeleteVariable|從MAT檔案中删去下一個MATLAB陣列
matPutVariableAsGlobal|從MATLAB陣列寫入到MAT檔案中
matGetVariableInfo|從MAT檔案中讀取MATLAB陣列頭資訊
matGetNextVariableInfo|從MAT檔案中讀取下一個MATLAB陣列頭資訊