How can I read block of data using textscan?

5 次查看(过去 30 天)
Hi guys, I am working with a block of data decribing some features of an element.
for each loop i need to read a block. My problem is that the code could only read the first variable,Lpp but could not read correctly lines 2,3 and 4.
Here is my attempt;
function[inp]= ReadInput
%%To read input file containing offset points
inp = struct; %Structure containing variable in the input file
inp.nstrp=10;
Input ='strpoffset1.txt';
fid=fopen(Input);
a=textscan(fid,'%f',1,'headerlines',4);
inp.Lpp=a{1}(1);
inp.xnstrp = zeros(inp.nstrp,1);
inp.nptstrp = zeros(inp.nstrp,1);
inp.offsets = cell(inp.nstrp,1);
for aa=1:inp.nstrp
b = textscan(fid,'%f',3); % Read next three line
inp.xnstrp(aa,1)= b{1}(2); % content of line 2 in the offset file
inp.nptstrp(aa,1)= b{1}(3); % content of line 3
c = textscan(fid,'%f %f',inp.nptstrp(aa,1)); % Read offset points
inp.offsets{aa}(:,1)= c{1}(:); % offset in y axis
inp.offsets{aa}(:,2)= c{2}(:); % offset in z axis
end
fclose(fid); %Close input file
end

采纳的回答

dpb
dpb 2020-4-15
编辑:dpb 2020-4-17
Basics are:
fnames={'Lpp','xnstrp','nptstrp','offsets','c'}; % define struct fieldnames
inp=cell2struct(cell(5,1),fnames,1); % build empty input struct
fid=fopen('strpoffset1.txt','r'); % open file
cleaner=onCleanup(@()fclose(fid)); % create cleanup fncn to close open file
hdr=num2cell(cell2mat(textscan(fid,'%f',4,'headerlines',4))); % read first header
c=textscan(fid,'%f %f\n',hdr{4},'CollectOutput',1); % read data array to cell array
inp=cell2struct([hdr;c],fieldnames(inp),1); % save first input struct array
i=1; % initialize counter
while ~feof(fid)
i=i+1; % increment counter
hdr=num2cell(cell2mat(textscan(fid,'%f',4))); % read next header
c=textscan(fid,'%f %f\n',hdr{4},'CollectOutput',1); % read data array to cell array
inp(i)=cell2struct([hdr;c],fieldnames(inp),1); % save into input struct array
%ADDENDUM -- ERROR CHECK FOR MISMATCHED ARRAY SIZE
if size(c{1},1)~=hdr{4}
error('Mismatched size: \nOffsets=%d, found %d elements',inp(i).offsets,size(c{1},1))
end
end
fid=fclose(fid);
Above doesn't preallocate for the struct array; if file isn't too big probably won't be a terrible issue...
Worked here for beginning of the file; the file attached, however, isn't regular -- the third begins like
3
24
14.5000
11
12 7.9567
1.462 7.9387
which doesn't look consistent -- altho will still be able to read. the "12" looks out of place but may be right.
The real problem will arise later because there are blank records and the number of header records turns to three instead of four.
If this is real, you'll have to read the file record-by-record and parse it unless it is known a priori what and where these changes occur so can code for them.
  5 个评论
Idris jae
Idris jae 2020-4-16
I think thats where my problem begins. I actually formulate the data to reflect waht i have in mind. my brain is blocked.
In my small knowledge, what I described above is what I expect to achieve.
What format will you advice to adopt to format the table better,pls.?
dpb
dpb 2020-4-16
We can't solve that for you...the file format that you start with in the example works ok as long as the whole file follows the rules -- but what you attached didn't:
...
2
24
14.00
12
1.461 7.9567
1.462 7.9387
1.046 7.7721
...
0.000 2.3055
0.000 2.1666
0.000 2.0718
3
24
14.5000
11
12 7.9567
1.462 7.9387
1.046 7.7721
...
0.000 2.3055
0.000 2.1666
4
24
15.00
13
1.461 7.9567
1.462 7.9387
...
0.000 2.1666
0.000 2.0718
0.000 1.9724
24
15.5000
10
1.461 7.9567
1.462 7.9387
1.046 7.7721
0.755 7.3652
0.62 7.2689
0.364 7.2024
0.241 7.1824
0.12 7.1299
0.000 7.0023
0.000 2.3055
The above section from the file that I shortened by eliding part of arrays for brevity is consistent for first two but as noted earlier the 3rd looks suspicious even though number of elements is consistent--the "12" in the first row of the array data looks very much like that's an error.
After that section, then group 4 looks ok again, but from then on it's a train wreck. There are a bunch of blank records and no section number so only three header records before the floating array.
Whatever created the input file looks to be broke -- you need to fix it first.

请先登录,再进行评论。

更多回答(2 个)

Idris jae
Idris jae 2020-4-16
Many thanks for your effort.
Attached is the amended table. surprisingly it wasnnt able to read from any neither your code nor mine

Idris jae
Idris jae 2020-4-16
but without the serial numbers, 1, 2... and introduce 4 spaces after the 1st block i generate the result. b{1}, instead of returning '-13.5' as the second variable, first 3 variable of the 3rd block were returned as 2nd
Input =
'strpoffset1.txt'
ans =
struct with fields:
nstrp: 8
Lpp: 24
xnstrp: [8×1 double]
nptstrp: [8×1 double]
offsets: {8×1 cell}
K>> b{1}
ans =
3.0000
24.0000
-14.5000
K>>
  3 个评论
dpb
dpb 2020-4-17
I added a sanity check for each section that those two are in synch -- if not, it now tells you and aborts.
Exercise for Student: I didn't put the section number that failed in the error message output...

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Large Files and Big Data 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by