Is it possible to loop a textscan?

4 visualizaciones (últimos 30 días)
Saeed Bello
Saeed Bello el 10 de Abr. de 2017
Editada: dpb el 11 de Abr. de 2017
I wrote a code in this form but could not read the data looping through textscan.
My deasire is the pick the header
Data looks like this:
CPNFC 2006/01/01 00:00:00
fmin =[---- ] foE =[---- ] h'E =[---- ] foE2 =[---- ]
fmin =[---- ] foE =[---- ] h'E =[---- ] foE2 =[---- ]
CPNFC 2006/01/01 00:15:00
fmin =[---- ] foE =[---- ] h'E =[---- ] foE2 =[---- ]
fmin =[---- ] foE =[---- ] h'E =[---- ] foE2 =[---- ]
''
''
''
%
fid = fopen(filename);
disp(filename)
format='%5s %4d/%02d/%02d %02d:%02d:%02d'
for m=1:4:6
[station,yyyy,mm,dd,hh,mn,ss] = textread(filename,format,m);
end
  2 comentarios
Stephen23
Stephen23 el 10 de Abr. de 2017
Your code shows textread, but it should be textscan.
The answer to your question is yes, you can call textscan in a loop.
You will need to allocate the output to some arrays, which get enlarged on each iteration. If you upload a sample file then we can show you how.
Saeed Bello
Saeed Bello el 10 de Abr. de 2017
Editada: Saeed Bello el 10 de Abr. de 2017
Thank you Stephen Cobeldick for your response. My goal is to extract the information from this attached file. First I want to pick all the header eg.g. CPNFC 2006/01/01 00:00:00,CPNFC 2006/01/01 00:15:00 in order to extract the date and time. Later work on picking the parameter e.g. h'F =[ 246 ] for each period. The raw data is attached.

Iniciar sesión para comentar.

Respuestas (2)

dpb
dpb el 10 de Abr. de 2017
Is the 'CPNC' string consistent throughout the file?
If so, read the whole file as cellstring array and just do findstr operation on the matching characters to locate the lines needed.
Alternatively, it appears that there are a fixed number of lines in each section; use that count to skip that many lines after the first...
Something like (caution air code...)
fmt=['%*s' {'yyyy/MM/dd HH:mm:SS'}%D]; % date format string for datetime variable
nH=15; % my count of records between headers
fid=fopen(...
d=textscan(fid,fmt,1); % first date/time
while ~feof(fid)
d=[d;textscan(fid,fmt,1,'headerlines',nH);
end
fid=fclose(fid);
Normally one doesn't want to "grow" an array dynamically, but for a single-time reading a relatively short file the overhead won't be too bad. If doing this over and over will be ongoing, then some efficiencies can be worked on.
  2 comentarios
Saeed Bello
Saeed Bello el 10 de Abr. de 2017
Yes the 'CPNC' string is consistent throughout the file I got this error after running your code
??? nH=15; % my count of records between headers
|
Error: The expression to the left of the equals sign is not a valid target for an
assignment.
dpb
dpb el 10 de Abr. de 2017
Editada: dpb el 11 de Abr. de 2017
Well, there's something else causing it then; that's a perfectly valid assignment statement. Check the preceding line is terminated with matching paren's,. quotes, etc., etc., ...
ADDENDUM
And, indeed, the format string was malformed...
>> fmt=['%*s %{yyyy/MM/dd}D %{HH:mm:ss}D %*[^\n]'];
>> while ~feof(fid)
d=[d;textscan(fid,fmt,1,'headerlines',16)];
end
>> whos d
Name Size Bytes Class Attributes
d 192x2 57952 cell
>> d{1,:}
ans =
2006/01/01
ans =
00:00:00
>>
As the note says it was air code; not tested.

Iniciar sesión para comentar.


Stephen23
Stephen23 el 10 de Abr. de 2017
Editada: Stephen23 el 11 de Abr. de 2017
Here is an alternative to a loop. This code specifies the * character to be the newline and calls textscan just once to read the entire file. This will be faster than using a loop and expanding arrays on each iteration.
opt = {'EndOfLine','*', 'Delimiter','=[]',...
'MultipleDelimsAsOne',true, 'CollectOutput',true};
fmt = repmat('%s',1,1+15*8);
fid = fopen('CPNFC20060101.txt','rt');
C = textscan(fid,fmt,opt{:});
fclose(fid);
C = C{1};
D = regexp(C(:,1),'\s+','split');
D = vertcat(D{:});
C(:,1) = D(:,4);
D = D(:,2:3);
The two output arrays are D, which contains the date and time, and C, which contains both the fieldnames and the field values. On advantage of this is that it makes it easy to construct a non-scalar structure containing all of the data:
E = genvarname(C(1,1:2:120));
E(2,:) = num2cell(regexprep(C(:,2:2:end),{'-+','\s+'},{'-',''}),1);
S = struct(E{:});
which makes accessing the data trivial:
>> S(2).(genvarname('h''Es'))
ans =
E
>> S(12).(genvarname('foEs'))
ans =
283JG
>> S(end).(genvarname('M(3000)F2'))
ans =
115
I tested on this file here:
  2 comentarios
Saeed Bello
Saeed Bello el 11 de Abr. de 2017
Thank you, Stephen. Your code has helped me to read the file into Matlab by calling textscan once (What a great relief form me). Iwas unable to get the date from the D array as you mentioned.
  • The challenge now is extracting the dates and time.
  • Kindly help me to extract the date and time separately.
Stephen23
Stephen23 el 11 de Abr. de 2017
@Saeed Bello: it is not clear to me what you are trying to do.
The cell array D contains two columns: the first with the date strings, the second with the time strings. You did not explain what you want to do with these strings, nor how you are trying to "extract" them. You did not even say what you want to the output to be. It is hard for me to help you if you do not give any information about what you are doing, and what you want.
Do you want to convert the date/time strings into date vectors, serial date numbers, datetime objects, or something else entirely?

Iniciar sesión para comentar.

Categorías

Más información sobre Data Type Conversion en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by