3

I know there are already a lot of questions about this topic out there. But all solutions are for certain cases. I try to find a highly generalized way to extract numerical data from cell arrays containing char.

Example data: lines = <779x88 char> (post-processed textscan data)

xtotal=   0.3414E-03   ytotal=   0.0000E+00  ztotal=   0.0000E+00   etotal=   0.0000E+00
xtotal=   0.7239E-03   ytotal=   0.0000E+00  ztotal=   0.0000E+00   etotal=   0.1875E-08
...
xtotal=   0.1788E-01   ytotal=   0.0000E+00  ztotal=   0.0000E+00   etotal=   0.9965E-06
xtotal=   0.2586E-01   ytotal=   0.0000E+00  ztotal=   0.0000E+00   etotal=   0.1992E-05

The following loop is doing what I want:

   n =  4;  %number of output values
off1 =  3;  %offset 1
off2 = 13;  %offset 2
L = size(lines,1);   %Length of cell array

index = strfind(lines(1,:),'=');   %find all indices in char for "="
value = zeros(L,n);                %pre-allocation

% read numerical values and write it into array
% for sure vectorization is possible, but that shouldn't be the topic now
for ii=1:L
    for jj=1:n  
    value(ii,jj) = str2double( lines(ii, index(jj)+off1:index(jj)+off2 ) );
    end
end

results to:

value = 

  0.0003       0         0         0
  0.0007       0         0    0.0000
...
183.1000       0         0   95.4900
183.1000       0         0   95.4900

Though it works fine for this case, I still have to define:

   n =  4;  %number of output values
off1 =  3;  %offset 1
off2 = 13;  %offset 2

which I don't want to determine for all my different input files I'm processing. The only thing I assume to be predetermined should be the delimiter "=", as it should be the same for all input files. So isn't there any reliable way to detect numerical data out of char arrays?

Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
  • You could replace `str2double` with `eval`. e.g. try this in Matlab: `A = eval('0.3E03')`. Although `str2double` should work... – Dan Oct 08 '13 at 13:49
  • you're right, the problem was the wrong offset of 12 instead of 13. So nevermind... thanks! back to topic ;) – Robert Seifert Oct 08 '13 at 13:56

1 Answers1

3

You can ask textscan to do that for you:

n =  4;  %number of output values
L = size(lines,1);
value = zeros(L,n);
for ii=1:L,
    value(ii,:) = cell2mat(textscan(lines(ii,:), '%*s%f')).';
end

now for 4 lines in your example it produces:

>> format shortE
>> value
value =
   3.4140e-04            0            0            0
   7.2390e-04            0            0   1.8750e-09
   1.7880e-02            0            0   9.9650e-07
   2.5860e-02            0            0   1.9920e-06
Mohsen Nosratinia
  • 9,844
  • 1
  • 27
  • 52
  • I wouldn't have thought about using textscan again also for the char array. Great idea! Actually `n=length(index)` - so even that can be left out. – Robert Seifert Oct 08 '13 at 14:10
  • @thewaywewalk Glad it helped. You mentioned that `lines` is _(post-processed textscan data)_. Maybe you can merge the calls to `textscan`. – Mohsen Nosratinia Oct 08 '13 at 14:15
  • well no, there is too much unwanted data I already filtered out before. Maybe there is a way, but it would definetely decrease the readability of the code. – Robert Seifert Oct 08 '13 at 14:19