Read string and data (double matrix) of uknown size from file "efficiently"
1 次查看(过去 30 天)
显示 更早的评论
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
0 个评论
采纳的回答
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 个评论
Fangjun Jiang
2011-7-5
Well, the search capability of MATLAB Answers really needs to be improved. Glad it worked for you. You might want to check if it works for all your files. I found that the output returned by importdata differs in different version of MATLAB.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Spreadsheets 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!