What is wrong with this FORTRAN to MATLAB conversion?
Show older comments
I'm running MATLAB R2016a Student and getting error messages. Here is the CNSMTX program:
fid=fopen('ZLS918_919_KCR_Test_Up_0.txt','r');
fmt_num0='%7f %7f %7f %7f %7f %7f %3f %3f %3f %3f %2f %24c';%FORMAT(6F7.0,4I3,I2,6A4)
fmt_num1='%7f %7f %7f %7f %7f %7f %7f %7f %7f %7f'; %FORMAT(10F7.0)
fmt_num2='%21c %7f %7f %7f %7f %7f %7f %7f'; %FORMAT(3A4,7F7.0)
%READ(20,106) XXL,SW,CBAR,B2,XMAC,XREF,S1CON,PUNCH,IDUM,IDUN,ITNGO,
% & (ITIT(I),I=1,6)
ProjectTitle=textscan(fid,'%4c',20); %FORMAT(20A4)
[XXL,SW,CBAR,B2,XMAC,XREF,S1CON,PUNCH,IPROP,IDUM,ITNGO,...
ITIT]=textscan(fid,fmt_num0,1) % line 13 in MATLAB
%READ(20,101) (XV(I),YV(I),H(I),XEA(I),C(I),EAANGL(I),TANL(I),
% 1 TANT(I),YE(I),XE(I),I=1,L)
for i=1:XXL
[XV(i),YV(i),H(i),XEA(i),C(i),EAANGL(i),TANL(i),TANT(i), ...
YE(i),XE(i)]=textscan(fid,fmt_num1,1)
end
Error using textscan Too many output arguments.
Error in CNSMTX (line 13) ITIT]=textscan(fid,fmt_num0,1)
5 Comments
Kenneth Lamury
on 6 Jul 2016
Kenneth Lamury
on 7 Jul 2016
Edited: Walter Roberson
on 7 Jul 2016
Star Strider
on 8 Jul 2016
It would be easier to help if you attached your data file here. Use the ‘paperclip’ icon.
Kenneth Lamury
on 9 Jul 2016
Edited: Walter Roberson
on 9 Jul 2016
Walter Roberson
on 9 Jul 2016
Instead of copying the file in as text, please use the paperclip to attach the file so we can download it.
Accepted Answer
More Answers (1)
Walter Roberson
on 7 Jul 2016
Edited: Walter Roberson
on 8 Jul 2016
0 votes
I repeat the concerns from http://www.mathworks.com/matlabcentral/answers/293547-can-one-read-one-line-of-string-title-followed-by-multiple-lines-of-numeric-data-like-fortran#comment_376916: field counts do not start until the first non-blank. The format you are using with '%7f %7f %7f' and so on implies that you are sure that you have a blank between fields and that the fields are definitely present and that the occupied portion of them is the exact width you indicate. If there are spaces between the fields and the fields are present for sure, then just use uncounted fields '%f%f%f' and so on . If there are not always spaces between fields then Yes you need a counted field, but to get that to work right you also need to have the case that the field is always fully occupied.
My previous response referred you to http://www.mathworks.com/matlabcentral/fileexchange/10866-fixed-width-import and I recommend you take a look at that.
The strategy I would use for fixed width fields that might not have spaces and might be partly occupied (typical Fortran output) would be to split the line into substrings of appropriate size (perhaps using mat2cell, since you can specify the number of columns for each cell), and then take a pass through the result doing sscanf() with uncounted format (because leading blanks) or just using str2double()
4 Comments
Kenneth Lamury
on 8 Jul 2016
Edited: James Tursa
on 8 Jul 2016
Walter Roberson
on 8 Jul 2016
You are being affected by the problem I have mentioned multiple times now: that the counts do not start until a non-blank. Because of this your reading is getting out of synchronization with your data. Your %24c is reading into the second line and is happening to leave the pointer positioned in a place that cannot match a %7f format because the 7 characters happens to include a blank.
Getting textscan to not skip leading blanks even with a %c or %[] specifier is tricky; to do it you need to set the 'Whitespace' option to '' (the empty string).
Take your numeric format and remove all of the blanks, because at the very least they lead the reader to expect blanks between fields. So not '%7f %3f' but '%7f%3f'
Then change all of the numeric format specifiers to %c format specifiers. So not '%7f%3f' but '%7c%3c' . And add 'Whitespace', '' to the textscan calls.
Then each place you go to extract numeric data from the cell array, use str2double(cellstr(XY{2})) (for example) on the entry. Notice the {} to extract the content of the entry and notice the cellstr to convert it from a char array to a cell array of strings to feed to str2double. However, if you only extracted from a single line then you can skip the cellstr() stage, such as str2double(XY{2})
Each place that you go to extract text data from the cell array, remember that when you use %c in textscan then the cell you get back will be a single char array, not a cell array of strings like %s or %[] would give you. Chances are that you are going to want to cellstr() the result before using it, if you extracted from multiple lines.
Kenneth Lamury
on 10 Jul 2016
Edited: Walter Roberson
on 10 Jul 2016
Walter Roberson
on 10 Jul 2016
The cell2mat(XXc) is going to fail. You can only cell2mat() if everything has the same data type, but you have the %21c at the end of the numerics.
Categories
Find more on Large Files and Big Data in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!