while文を使ったファイル終端までのデータ読み込み †一連のフォーマットがファイルの中で何回続くかわからない時に, while ~feof(fid) を使ってファイルの最後まで読み取る(fidはfopenで開いたファイルID). ファイル形式例 †例として,ny行nx列の値が時系列で並ぶ,とある量 f(x,y,t) を仮定し, 2017/01/01 00:00:00 f( 1, 1,1) f( 2, 1,1) f( 3, 1,1) ... f(nx, 1,1) f( 1, 2,1) f( 2, 2,1) f( 3, 2,1) ... f(nx, 2,1) f( 1, 3,1) f( 2, 3,1) f( 3, 3,1) ... f(nx, 3,1) ... ... ... ... ... f( 1,ny,1) f( 2,ny,1) f( 3,ny,1) ... f(nx,ny,1) 2017/01/01 00:10:00 f( 1, 1,2) f( 2, 1,2) f( 3, 1,2) ... f(nx, 1,2) f( 1, 2,2) f( 2, 2,2) f( 3, 2,2) ... f(nx, 2,2) .... というように, 事前作業 †どちらも共通の作業として, % % preallocate nt_upper = 1000; header = cell(nt_upper,1); dataorg = cell(nt_upper,1); % % open fid = fopen(filename,'r'); のように,ファイルを開き配列の事前割当てをする. textscan †ヘッダー(時刻)と数値配列用で2種類の読み取り形式(FormatSpec)を用意する. % % format fmt_head = '%s%s%*[^\n]'; % header fmt = [repmat('%f',[1 nx]),'\n']; % matrix % % read i = 1; while ~feof(fid) header{i} = textscan(fid,fmt_head,1); dataorg{i} = cell2mat(textscan(fid,fmt,ny)); i = i + 1; end 数値配列を読むところでは,「cell2mat」がないと,セル配列の中にセル配列が入るので厄介. fscanf †文字列を読み込むのにfscanfは不便なので,fgetlを使う. % % format fmt = [repmat('%f',[1 nx*ny]),'\n']; % % read i = 1; while ~feof(fid) header{i} = fgetl(fid); dataorg{i} = fscanf(fid,fmt,[nx ny])'; i = i + 1; end "[nx ny]"で読みその後転置しなければ,ファイルの配置通りに読めないことに注意. おわりに †また,textscanとfscanfの両方,読み終えた後に余分に宣言した分の空白セルを削除するため, % % delete empty cells header(i:end) = []; dataorg(i:end) = []; をしてスマートに. 参考 † |