Saturday, November 23, 2013

Read a row of an Excel CSV file in Matlab

The only issue with CSV files in matlab is that they sometimes have commas between quotes. I wrote this function that parses the CSV file into an array of cells, but leaves the text with commas. It also figures which entries are numbers and converts those.
function result=xlscsvlineparse(p_line)
%the p_line is just a character array, we loop to find the beginning and
%end of the commas unless there are quotes around them.
    i_comma=1;
    i_counter=0;
    i_linelength=length(p_line);
    for i=1:i_linelength      
        if(p_line(i)==',')
            if(i_comma==1)
                i_counter=i_counter+1;
                a_comma(i_counter) = i;
            end
        elseif(p_line(i)=='"')
            if(i_comma==1)
                i_comma=0;
            else
               i_comma=1; 
            end
        end  
    end
    %now that I have a line, make a cell array based upon what was there
    i_cellc=1;
    i_start=1;
    for i_counter=1:length(a_comma)
       i_end=a_comma(i_counter);
       %fprintf('%s\n',p_line(i_start:i_end)); 
       a_cell{i_cellc}=sprintf('%s',p_line(i_start:i_end));
       i_cellc=i_cellc+1;
       i_start=i_end;
    end
   
    % there still should be one more here, but it's missing because of 
    % the fact that the last ,EOL is not parsed.  
    if(a_comma(length(a_comma))==i_linelength)
        a_cell{i_cellc}=',,';
    else
        a_cell{i_cellc}=sprintf('%s',p_line(i_start:i_linelength));
    end
    %strip out the , if it starts or ends the cell string.
    for i_counter=1:length(a_cell)
        tmp_cell = a_cell{i_counter};
        if(tmp_cell(1)==',')
            tmp_cell=tmp_cell(2:end);
        end
        if(tmp_cell(end)==',')
            tmp_cell=tmp_cell(1:end-1);
        end
       %convert numbers to numbers
        if(valid_number(tmp_cell)==1)
            tmp_cell=str2num(tmp_cell);
        end
        a_cell{i_counter}=tmp_cell;
       % fprintf('%i: %s\n',i_counter,a_cell{i_counter});
    end
    result=a_cell;
end

function result=valid_number(s_str)
%this function return if s_str is a valid number
i_tick=1;  %default to valid.
a_int=char(s_str);  %to ASCII
    for i_counter=1:length(a_int);
        c_tmp=a_int(i_counter);
        if((c_tmp>=48)&&(c_tmp<=57))
            %nothing
        elseif(c_tmp==46)
            %nothing    
        else
           i_tick = i_tick -1; 
        end;        
    end
    result=i_tick;
end

No comments:

Post a Comment