function result= dlmread_mod(filename,delimiter,r,c,range)
%DLMREAD Read ASCII delimited file.
% RESULT = DLMREAD(FILENAME) reads numeric data from the ASCII
% delimited file FILENAME. The delimiter is inferred from the formatting
% of the file.
%
% RESULT = DLMREAD(FILENAME,DELIMITER) reads numeric data from the ASCII
% delimited file FILENAME using the delimiter DELIMITER. The result is
% returned in RESULT. Use '\t' to specify a tab.
%
% When a delimiter is inferred from the formatting of the file,
% consecutive whitespaces are treated as a single delimiter. By
% contrast, if a delimiter is specified by the DELIMITER input, any
% repeated delimiter character is treated as a separate delimiter.
%
% RESULT = DLMREAD(FILENAME,DELIMITER,R,C) reads data from the
% DELIMITER-delimited file FILENAME. R and C specify the row R and column
% C where the upper-left corner of the data lies in the file. R and C are
% zero-based so that R=0 and C=0 specifies the first value in the file.
%
% All data in the input file must be numeric. DLMREAD does not operate
% on files containing nonnumeric data, even if the specified rows and
% columns for the read contain numeric data only.
%
% RESULT = DLMREAD(FILENAME,DELIMITER,RANGE) reads the range specified
% by RANGE = [R1 C1 R2 C2] where (R1,C1) is the upper-left corner of
% the data to be read and (R2,C2) is the lower-right corner. RANGE
% can also be specified using spreadsheet notation as in RANGE = 'A1..B7'.
%
% DLMREAD fills empty delimited fields with zero. Data files where
% the lines end with a non-space delimiter will produce a result with
% an extra last column filled with zeros.
%
% See also DLMWRITE, TEXTSCAN, LOAD, FILEFORMATS.
% Obsolete syntax:
% RESULT= DLMREAD(FILENAME,DELIMITER,R,C,RANGE) reads only the range specified
% by RANGE = [R1 C1 R2 C2] where (R1,C1) is the upper-left corner of
% the data to be read and (R2,C2) is the lower-right corner. RANGE
% can also be specified using spreadsheet notation as in RANGE = 'A1..B7'.
% A warning will be generated if R,C or both don't match the upper
% left corner of the RANGE.
% Copyright 1984-2006 The MathWorks, Inc.
% $Revision: 5.40.4.13 $ $Date: 2006/10/02 16:32:30 $
% Validate input args
fid = -1;
if nargin==0
error('MATLAB:dlmread:Nargin','Not enough input arguments.');
end
% Get Filename
if ~ischar(filename)
error('MATLAB:dlmread:InvalidInputType','Filename must be a string.');
end
% Get Delimiter
if nargin==1 % Guess default delimiter
[fid message] = fopen(filename);
if fid < 0
error('MATLAB:dlmread:FileNotOpened',...
'The file ''%s'' could not be opened because: %s',filename,message);
end
str = fread(fid, 4096,'*char')';
frewind(fid);
delimiter = guessdelim(str);
if isspace(delimiter);
delimiter = '';
end
else
delimiter = sprintf(delimiter); % Interpret \t (if necessary)
end
if length(delimiter) > 1,
error('MATLAB:dlmread:InvalidDelimiter',...
'DELIMITER must be a single character.');
end
% Get row and column offsets
offset = 0;
if nargin<=2, % dlmread(file) or dlmread(file,dim)
r = 0;
c = 0;
nrows = -1; % Read all rows
range = [];
elseif nargin==3, % dlmread(file,delimiter,range)
if length(r)==1, % Catch obsolete syntax dlmread(file,delimiter,r)
warning('MATLAB:dlmread:ObsoleteSyntax',...
'Obsolete syntax. C must be specified with R.');
result= dlmread(filename,delimiter,r,0);
return
end
range = r;
if ischar(range)
range = str2rng(range);
end
r = range(1);
c = range(2);
nrows = range(3) - range(1) + 1;
elseif nargin==4, % dlmread(file,delimiter,r,c)
nrows = -1; % Read all rows
range = [];
elseif nargin==5, % obsolete syntax dlmread(file,delimiter,r,c,range)
if ischar(range)
range = str2rng(range);
end
rold = r; cold = c;
if r > range(3) || c > range(4), result= []; return, end
if r ~= range(1) || c ~= range(2)
warning('MATLAB:dlmread:InvalidRowsAndColumns',...
['R and C should match RANGE(1:2). Use DLMREAD(FILE,DELIMITER,RANGE)' ...
' instead.'])
offset = 1;
end
% For compatibility
r = max(range(1),r);
c = max(range(2),c);
nrows = range(3) - r + 1;
end
% attempt to open data file
if fid == -1
[fid message] = fopen(filename);
if fid < 0
error('MATLAB:dlmread:FileNotOpened',...
'The file ''%s'' could not be opened because: %s',filename,message);
end
end
% Read the file using textscan, modified from dlmread to read strings
try
if isempty(delimiter)
result = textscan(fid,'%s',nrows,'headerlines',r,'headercolumns',c,...
'returnonerror',0,'emptyvalue',0, 'CollectOutput', true);
else
delimiter = sprintf(delimiter);
whitespace = setdiff(sprintf(' \b\t'),delimiter);
result = textscan(fid,'%s',nrows,...
'delimiter',delimiter,'whitespace',whitespace, ...
'headerlines',r,'headercolumns',c,...
'returnonerror',0,'emptyvalue',0,'CollectOutput', true);
end
catch
fclose(fid);
rethrow(lasterror);
end
% close data file
fclose(fid);
result = result{1};
% textscan only trims leading columns, trailing columns may need clipping
if ~isempty(range)
ncols = range(4) - range(2) + 1;
% adjust ncols if necessary
if ncols ~= size(result,2)
result= result(:,1:ncols);
end
end
% num rows should be correct, textscan clips
if nrows > 0 && nrows ~= size(result,1)
error('Internal size mismatch')
end
% When passed in 5 args, we have an offset and a range. If the offset is
% not equal to the top left corner of the range the user wanted to read
% range Ai..Bj and start looking in that matrix at rold and cold. For
% backwards compatibility we create a result the same size as the specified
% range and place the data in the result at the requested offset.
% For example, given a file with [1 2 3; 4 5 6], reading A1..C2 with offset
% 1,2 produces this result:
% 0 0 0
% 0 5 6
if nargin==5 && offset
rowIndex = rold+1:rold+nrows;
columnIndex = cold+1:cold+ncols;
if rold == 0
rowIndex = rowIndex + 1;
end
if cold == 0
columnIndex = columnIndex + 1;
end
% assign into a new matrix of the desired size
% need to create temp matrix here cuz we want the
% offset region filled with zeros
new_result(rowIndex,columnIndex) = result;
result = new_result;
end