MATLAB Answers

Read string and data (double matrix) of uknown size from file "efficiently"

8 ビュー (過去 30 日間)
dm
dm 2011 年 7 月 5 日
I'm working with converting a piece of Scilab code to MATLAB, where I want to process data in some text files that I got. The content of the text files may, for example, be on the form:
C:\some\dir\blabla\file.s2p
freq re(r1) im(r1) re(r2) im(r2) re(r3) im(r3) re(r4) im(r4)
1 2 3 4 5 6 7 8 9
3 4 5 6 7 8 9 9 1
2 3 4 5 6 7 7 2 3
etc (the first line is always a path to another file, and the second line always holds a number of variable names equal to the number of columns in the data matrix).
The thing is that the number of rows and columns with data in different files may vary, so I have to write my function to handle the general case. In the end, what I want to read into MATLAB for processing is the path to the s2p-file given at the first line of the text file, and the real data matrix which is separated by white-spaces.
In the original Scilab code this is done by the function fscanfMat (http://help.scilab.org/docs/5.3.2/en_US/fscanfMat.html), but I can't find any equivalent in MATLAB.
I've written a small hack in MATLAB which does the job for now, but I don't think it's a good piece of code, so I'm looking for hints for improving it, and maybe even make it a bit more "elegant".
The code I use atm is
function [A sfilename] = fscanfMat(filename)
dummyfile = ['dummy_' filename]; % temporarily for storing matrix
fid1 = fopen(filename,'r'); % open original file
fid2 = fopen(dummyfile,'w'); % open dummy file
linenum = 1; % use to store first line in text file
k = 1; % use to avoid computing numcols, etc, in each iteration
while 1
tline = fgetl(fid1); % read line into string
if linenum == 1
sfilename = tline; % store first line
linenum = linenum+1;
end
if tline == -1 % end of file
break;
end
if ~isnan(str2double(tline(1))) && k == 1 % compute numcols, etc
numcols = length(regexp(tline,' ','split')); % number of columns in data
strformat = repmat('%s ',1,numcols); % for writing to file
floatformat = repmat('%f ',1,numcols); % for reading from file
k = k+1;
end
if ~isnan(str2double(tline(1))) % reached data in text file
fprintf(fid2,strtrim(strformat),tline); % print to dummy
fprintf(fid2,'\n');
end
end
fclose(fid2); % can't read from file (w+ doesn't work either for fid2)
fid2 = fopen(dummyfile,'r'); % re-open for reading
A = textscan(fid2,floatformat); % read data matrix into cell array
A = cell2mat(A); % convert to double matrix
fclose(fid1); % close original file
fclose(fid2); % close dummy
end
It's not an exact copy of the functionalities of the Scilab version, but since I only need the first line as a string in MATLAB, I ignore the second line with string data.
So the big question is: any hints on how I can improve this when I don't know the size of the data matrix I want to read into MATLAB (if I knew, making the formatting string would be easy, but as for now I can't see a good solution by myself).
Best regards, dm

採用された回答

Fangjun Jiang
Fangjun Jiang 2011 年 7 月 5 日
Try importdata(). It might work for you depending on your MATLAB version.
>> a=importdata('test.csv')
a =
data: [3x9 double]
textdata: {2x9 cell}
colheaders: {1x9 cell}
>> a.data
ans =
1 2 3 4 5 6 7 8 9
3 4 5 6 7 8 9 9 1
2 3 4 5 6 7 7 2 3
>> a.textdata
ans =
Columns 1 through 7
[1x27 char] [] [] [] [] [] []
'freq' 're(r1)' 'im(r1)' 're(r2)' 'im(r2)' 're(r3)' 'im(r3)'
Columns 8 through 9
[] []
're(r4)' 'im(r4)'
>> a.colheaders
ans =
Columns 1 through 7
'freq' 're(r1)' 'im(r1)' 're(r2)' 'im(r2)' 're(r3)' 'im(r3)'
Columns 8 through 9
're(r4)' 'im(r4)'
  3 件のコメント
dm
dm 2011 年 7 月 5 日
I'm running some tests now, so far it works excellent on the version I have installed (R2011a), so I think I'll go for this solution (can just write a small note/warning in the header if we are to hand over our MATLAB code of the software back to the company who provided the Scilab one).

サインインしてコメントする。

その他の回答 (0 件)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by