No BSD License  

Highlights from
readascii

from readascii by alex sanchez
Reads ascii files and prepares them for load compatibility.

readascii(argin)
function argout = readascii(argin)
% Reads ASCII Files
%
% USAGE:
%   argout = readascii(argin)
%
% DESCRIPTION:
%   Reads an ascii file and returns (if nargout==1)
%   a structure with several fields including the 
%   headers, text and nuemrica data. 
%   If the name for an out-file is given, 
%   the file is changed for MatLab load
%   compatibility commenting all "text" lines and 
%   inserting NaN'. The out file may be saved as 
%   binary, which only saves the data of the in-file.
%
% INPUT VARIABLE:
%   argin is a structure array with fields:
%       infile = file to be read 
%       outfile = name of out-file (only if given)
%       outperm = permision for out file used for fopen.m
%               examples - 'w', 'wb', 'a+', etc
%               default - 'w'    
%       outprec = precision for out file used for fwrite.m
%               examples - 'uchar', 'int8', 'single', 'double'
%               default - 'uchar'
%       old = text or numbers that want to be replaced
%               If more than one number or text needs to be 
%               replaced, old may be given as a cell array 
%               examples - -9999, {'0000','-----'}
%               default - '*****'
%       new = text or number that replaces old
%               default - 'NaN'
%
% OUTPUT VARIABLE:
%   argout is a structure array with the same fields as argin, plus:
%       header(s) = heading of file and/or any row with characters other
%               than e that are commented in an ascii out file
%               any line starting with % or any non alphabet characters
%       text = string data in file
%       data = vector or matrix with data read from file
%       flag = text indicating whether all data was read,
%               if there exist rows with different 
%               number of columns in the in file, and 
%               the amount of data written to a binary file
%
% NOTES:
%   Using outfile == infile is valid but slows 
%   the program down considerably.
%   The uigetfile dialog is invoked if nargin==0.
%   Commenting a linea twice or any data linea with NaN' is avoided.
%   Only permits writing to binary file if the ascii file contains
%   only one data size
%
%Copy-Left, Alejandro Sanchez

if nargin==0
    [file,fpath]=uigetfile('*.*','Select In-File:');
	if ~any(file), return, end
	argin.infile=[fpath,file];  
end %if

if nargin==1 && ~isstruct(argin)
    argin.infile=argin;
end

finid=fopen(argin.infile,'r');
if finid < 0
    error(['Could not open file: ',argin.infile])
end

if nargin==0
    disp('--------------- IN-FILE --------------------------')
    type(argin.infile)
    disp('----------------- READASCII ------------------------')
    quest = input('Do you want to write the data read to a file? (Yes=1,No~=1)\n');
    if isempty(quest)
        quest = 0;
    end
    if quest==1
        [filename,filepath]=uiputfile('*.*','Save data as');
        argin.outfile = [filepath,filename];
    end
    quest = input('Do you want to replace something in the file? (Yes=1,No~=1)\n');
    if isempty(quest)
        quest = 0;
    end
    if quest==1
%         argin.old = inputdlg({strvcat('Enter the text you want to',...
%             'replace. e.g. 9999, port'),'','',''},...
%             'readascii.m');
        disp('Enter want you want to change as a cell')
        argin.old = eval(input('e.g. {''NaN'', ''Port''} \n',''));
    end
    if isfield(argin,'old')
        for k=length(argin.old):-1:1
            if isempty(argin.old{k})
                argin.old{k} = [];
            else
                break
            end
        end
    end
end

if ~isfield(argin,'old')
    old{1} = '*****';
elseif ischar(argin.old)
    old{1} = argin.old;
elseif isnumeric(argin.old)
    for k=1:length(argin.old)
        old{k} = num2str(argin.old(k));
    end %for
elseif iscell(argin.old)
    old = argin.old;
    for k=1:length(old)
        if isnumeric(old{k})
            old{k} = num2str(old{k});
        end %if
    end %for
end
Nold = length(old);

if ~isfield(argin,'new')
    new{1} = 'NaN';
end
if isnumeric(new)
    new{1} = num2str(new);
elseif iscell(new)
    Nnew = length(new);
    for k=1:Nold
        if k>Nnew
            new{k} = new{k-1};
        end
        if isnumeric(new{k})
            new{k} = num2str(new{k});
        end
    end %for
end

exout = isfield(argin,'outfile');

if exout
    if ~isfield(argin,'outperm')
        argin.outperm='w';
    end %if
    if ~isfield(argin,'outprec') 
        argin.outprec='uchar';
    end %if
    isasc = strcmpi(argin.outprec,'uchar');
    if strcmp(argin.outfile,argin.infile)
        argin.outfile = 'readfile.tmp';
    end %if
    foutid=fopen(argin.outfile,argin.outperm);
    if foutid < 0
        fclose(finid);
        error(['Could not open file: ',argin.outfile])
    end %if
end %if

h = cell(1); %headers
s = h; %strings
d = h; %numeric data
e = 1; %counter for data
g = e; %counter for headers
j = e;%counter for string data
c = e; %flag to indicate type of data of previous line
%c=0 -> header
%c=1 -> numeric data
%c=2 -> text
flag = [];

while 1
    linea = fgetl(finid);
    if ~ischar(linea), break, end
    linep = linea;
    if ~isempty(linea) %skip
        %Replaces old with new in all of file
        for j=1:Nold
           linea = strrep(linea,old{j},new{j});
        end %for
        %Communly used for dates
        %These are replaced by default
        linea = strrep(linea,'/',' ');
        linea = strrep(linea,':',' ');
        linea = strrep(linea,'"',' ');
    
        %Check if it can be converted into a number
        try
            nline = eval(['[',linea,']']);
        catch
            nline = [];
        end
    
        %if nline is empty than the linea is a string
        if ~isempty(nline)
            %Check if it is not the same number 
            %of columns as the previous data set than
            %a new data set is made
            if isempty(d{e})
                d{e} = nline;
                s2 = size(d{e},2);
            elseif s2==size(nline,2) && c==1
                d{e} = [d{e}; nline];
            else
                e = e + 1;
                d{e} = nline;
                s2 = size(nline,2);
                if exout
                    flag='Warning: Posible Data Set with Irregular Number of Columns';
                end %if
            end
            c = 1;
        %If the linea is a string
        else
            %deblank and change to upper case
            LINEA = upper(linea(~isspace(linea)));
            if (LINEA(1)<'A') || (LINEA(1)>'Z')
                if isempty(h{g})
                    h{g} = linep;
                elseif c==0
                    h{g} = char(h{g},linep);
                else
                    g = g + 1;
                    h{g} = linep;
                end
                c = 0;       
            else
                if isempty(s{j})
                    s{j} = linep;
                elseif c==2
                    s{j} = char(s{j},linep);
                else
                    j = j + 1;
                    s{j} = linep;
                end
                c = 2;
            end %if
            %Avoids commenting twice
            if ~isequal(LINEA(1),'%') && exout
                linea = ['% ',linep];
            end %if
        end %if
        if exout && isasc
    	    fwrite(foutid,linea);
        end %if
    end %if
end %for

if isempty(flag)
    flag = 'All data Read';
end

if exout && ~isasc
    dw = fwrite(foutid,d{1},argin.outprec);
    flag = [flag,' && ',num2str(dw),...
            ' (',num2str(size(d,1)),...
            'x',num2str(size(d,2)),') Written'];
end

fclose(finid);
if isfield(argin,'outfile')
    fclose(foutid);
    if strcmp(argin.outfile,'readfile.tmp')
        copyfile(argin.outfile,argin.infile);
        delete('readfile.tmp')
    end
end

if (nargout==1) || (nargin==0)
    argout = argin;
    if length(h)==1
        argout.headers = h{1};
    else
        argout.headers = h;
    end
    if length(s)==1
        argout.text = s{1};
    else
        argout.text = s;
    end
    if length(d)==1
        argout.data = d{1};
    else
        argout.data = d;
    end
    argout.flag = flag;
end

return


Contact us at files@mathworks.com