テキスト ファイルからの数値データ ブロックのインポート
この例では、テキスト ファイル内でブロックに編成された数値データを読み取る方法を説明します。ファイル内の各ブロックは、形式が異なっていてもかまいません。すべてのブロックは、textscan
を使用して、一度に 1 ブロックずつ cell 配列として読み取ることができます。
ファイル形式の概要
サンプル テキスト ファイル test80211.txt
の情報はワイヤレス ネットワーク通信の品質テストの結果です。サンプル ファイルは、前書きの 4 行と、それに続くいくつかのデータ ブロックで構成されています。各ブロックは異なる環境 (たとえば、モバイル、屋内、屋外) を表し、次の形式をもっています。
2 行の説明記述のヘッダー行
テキスト
Num SNR=
およびそれに続く数値m
m
列と任意の行数の table に整理された数値データ (データはコンマ区切り)ブロックの終了を示すテキスト
*
EOB
たとえば、データ ブロックは次のような形式になります。
* Indoor2
* SNR Vs test No
Num SNR=3
,-5.00E+00,-4.00E+00,
1.00E+00,3.32E-07,9.12E-07
2.00E+00,1.49E-07,2.44E-07
3.00E+00,6.04E-07,2.53E-07
4.00E+00,1.53E-07,4.25E-07
5.00E+00,1.82E-07,1.83E-07
6.00E+00,6.27E-07,8.21E-07
7.00E+00,9.10E-08,1.53E-08
8.00E+00,8.73E-07,6.45E-07
9.00E+00,4.40E-07,1.33E-07
*EOB
数値データは、多数の独立したテストにおける、あるノイズ レベル範囲にわたるエラー率を示します。1 列目はテスト番号を表します。サンプル ファイル全体を表示するには、コマンド ラインで以下を入力します。
open test80211.txt
読み取るためテキスト ファイルを開く
ファイルを開き、ファイルの識別子を作成します。
fileID = fopen('test80211.txt','r');
概要行の読み取り
改行文字で区切られたテキストを含む先頭の 4 行を読み取ります。textscan
は、文字ベクトルの 4 行 1 列の cell 配列を含んだ 1 行 1 列の cell 配列を返します。
Intro = textscan(fileID,'%s',4,'Delimiter','\n')
Intro = 1x1 cell array
{4x1 cell}
最初の cell の内容を表示します。
disp(Intro{1})
{'*CCX' } {'*CCX WiFi conformance test'} {'*CCX BER Results' } {'*CCX' }
各ブロックの読み取り
各ブロックのヘッダー、数値 m
、データの列ヘッダーを読み取ってから、データ自体を読み取ります。最初に、ブロックのインデックスを初期化します。
Block = 1;
while
ループ内で各データ ブロックを読み取ります。ループは、ファイルの最後に到達し ~feof
が false
を返すまで実行されます。関数 textscan
は、各ブロックのデータを InputText
という名前の cell 配列として返します。cell2mat
を使用して各 cell 配列を数値配列に変換し、その数値配列を Data
という名前の cell 配列に格納します。cell 配列を使用すると、サイズの異なる複数のブロックを格納できます。
while (~feof(fileID)) % For each block: fprintf('Block: %s\n', num2str(Block)) % Print block number to the screen InputText = textscan(fileID,'%s',2,'delimiter','\n'); % Read 2 header lines HeaderLines{Block,1} = InputText{1}; disp(HeaderLines{Block}); % Display header lines InputText = textscan(fileID,'Num SNR = %f'); % Read the numeric value % following the text, Num SNR = NumCols = InputText{1}; % Specify that this is the % number of data columns FormatString = repmat('%f',1,NumCols); % Create format string % based on the number % of columns InputText = textscan(fileID,FormatString, ... % Read data block 'delimiter',','); Data{Block,1} = cell2mat(InputText); [NumRows,NumCols] = size(Data{Block}); % Determine size of table disp(cellstr(['Table data size: ' ... num2str(NumRows) ' x ' num2str(NumCols)])); disp(' '); % New line eob = textscan(fileID,'%s',1,'delimiter','\n'); % Read and discard end-of-block marker Block = Block+1; % Increment block index end
Block: 1
{'* Mobile1' } {'* SNR Vs test No'}
{'Table data size: 30 x 19'}
Block: 2
{'* Mobile2' } {'* SNR Vs test No'}
{'Table data size: 30 x 9'}
Block: 3
{'* Mobile3' } {'* SNR Vs test No'}
{'Table data size: 31 x 15'}
Block: 4
{'* Mobile4' } {'* SNR Vs test No'}
{'Table data size: 28 x 19'}
Block: 5
{'* Mobile5' } {'* SNR Vs test No'}
{'Table data size: 32 x 18'}
Block: 6
{'* Mobile6' } {'* SNR Vs test No'}
{'Table data size: 30 x 19'}
Block: 7
{'* Mobile7' } {'* SNR Vs test No'}
{'Table data size: 30 x 11'}
Block: 8
{'* Mobile8' } {'* SNR Vs test No'}
{'Table data size: 20 x 18'}
Block: 9
{'* Indoor0' } {'* SNR Vs test No'}
{'Table data size: 9 x 3'}
Block: 10
{'* Indoor1' } {'* SNR Vs test No'}
{'Table data size: 22 x 6'}
Block: 11
{'* Indoor2' } {'* SNR Vs test No'}
{'Table data size: 25 x 3'}
Block: 12
{'* Indoor3' } {'* SNR Vs test No'}
{'Table data size: 21 x 18'}
Block: 13
{'* Outdoor1' } {'* SNR Vs test No'}
{'Table data size: 20 x 18'}
Block: 14
{'* Outdoor2' } {'* SNR Vs test No'}
{'Table data size: 23 x 3'}
Block: 15
{'* Outdoor3' } {'* SNR Vs test No'}
{'Table data size: 22 x 18'}
Block: 16
{'* Outdoor4' } {'* SNR Vs test No'}
{'Table data size: 21 x 18'}
Block: 17
{'* Outdoor5' } {'* SNR Vs test No'}
{'Table data size: 18 x 5'}
テキスト ファイルを閉じる
fclose(fileID);
ブロックの総数
ファイル内のブロック数を求めます。
NumBlocks = Block-1
NumBlocks = 17
数値データの表示
short 型科学表記を使用して、1 つのブロック中の数値データを表示します。
最初に、現在のコマンド ウィンドウの出力表示形式を保存します。
user_format = get(0, 'format');
表示形式を short 型科学表記に変更します。
format shortE
9 番目のブロックのヘッダー行と数値データを表示します。
Block = 9; disp(HeaderLines{Block});
{'* Indoor0' } {'* SNR Vs test No'}
fprintf('SNR %d %d\n',Data{Block,1}(1,2:end))
SNR -7 -6
disp(Data{Block,1}(2:end,2:end));
9.0600e-07 6.7100e-07 3.1700e-07 3.5400e-07 2.8600e-07 1.9600e-07 1.4800e-07 7.3400e-07 3.9500e-08 9.6600e-07 7.9600e-07 7.8300e-07 4.0000e-07 8.8100e-07 3.0100e-07 2.9700e-07
元のコマンド ウインドウ出力表示形式に戻します。
set(0, 'format', user_format);