Mercurial > hg > octave-lyh
changeset 12878:875c735c0929
Limit the output of strread to the specified length.
* strread.m: Limit the length of output to the number of repeated formats.
Add a test.
author | Ben Abbott <bpabbott@mac.com> |
---|---|
date | Sun, 24 Jul 2011 18:04:16 -0500 |
parents | ddea3962b024 |
children | c3b305e7e59f |
files | scripts/io/strread.m |
diffstat | 1 files changed, 24 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/io/strread.m +++ b/scripts/io/strread.m @@ -26,9 +26,10 @@ ## ## The string @var{str} is split into words that are repeatedly matched to the ## specifiers in @var{format}. The first word is matched to the first -## specifier, the second to the second specifier and so forth. If there are -## more words than specifiers, the process is repeated until all words have -## been processed. +## specifier, +## the second to the second specifier and so forth. If there are more words +## than +## specifiers, the process is repeated until all words have been processed. ## ## The string @var{format} describes how the words in @var{str} should be ## parsed. @@ -223,12 +224,9 @@ case "returnonerror" err_action = varargin{n+1}; case "treatasempty" - if (iscellstr (varargin{n+1})) - empty_str = varargin{n+1}; - elseif (ischar (varargin{n+1})) - empty_str = varargin(n+1); - else - error ('strread: "treatasempty" value must be string or cellstr'); + empty_str = varargin{n+1}; + if (ischar (empty_str)) + empty_str = {empty_str}; endif otherwise warning ('strread: unknown property "%s"', varargin{n}); @@ -236,7 +234,11 @@ endfor ## Parse format string to compare nr. of conversion fields and nargout - nfields = length (strfind (format, "%")) - length (strfind (format, "%*")); + idx = strfind (format, "%")'; + specif = format([idx, idx+1]); + nspecif = length (idx); + idx_star = strfind (format, "%*"); + nfields = length (idx) - length (idx_star); ## If str only has numeric fields, a (default) format ("%f") will do. ## Otherwise: if ((max (nargout, 1) != nfields) && ! strcmp (format, "%f")) @@ -298,7 +300,6 @@ if (! isempty (white_spaces)) ## Check for overlapping whitespaces and delimiters & trim whitespace - ## FIXME: Can this section be replaced by call to setdiff() ? if (! isempty (delimiter_str)) [ovlp, iw] = intersect (white_spaces, delimiter_str); if (! isempty (ovlp)) @@ -356,12 +357,15 @@ endif num_words = numel (words); ## First guess at number of lines in file (ignoring leading/trailing literals) - num_lines = ceil (num_words / num_words_per_line); + if (format_repeat_count > 0) + num_lines = format_repeat_count; + else + num_lines = ceil (num_words / num_words_per_line); + endif ## Replace TreatAsEmpty char sequences by empty strings if (! isempty (empty_str)) ## FIXME: There should be a simpler way to do this with cellfun - ## or possibly with regexprep for ii = 1:numel (empty_str) idz = strmatch (empty_str{ii}, words, "exact"); words(idz) = {""}; @@ -393,7 +397,7 @@ ## 1. Assess "period" in the split-up words array ( < num_words_per_line). ## Could be done using EndOfLine but that prohibits EndOfLine = "" option. fmt_in_word = cell (num_words_per_line, 1); - words_period = litptr = 1; + words_period = 1; ## For each literal in turn for ii = 1:numel (idy) fmt_in_word(idy(ii)) = num_words; @@ -407,7 +411,9 @@ endif endfor words_period = max (words_period, litptr); - num_lines = ceil (num_words / words_period); + if (format_repeat_count < 0) + num_lines = ceil (num_words / words_period); + endif ## 2. Pad words array so that it can be reshaped tmp_lines = ceil (num_words / words_period); @@ -492,7 +498,7 @@ end_try_catch endif - + ## For each specifier, process corresponding column k = 1; for m = 1:num_words_per_line @@ -691,3 +697,5 @@ %! c = textscan (str, "Text%*dText%dText"); %! assert (c{1}, [2; 4; NaN]); +%!assert (isequal (strread ("1 2 3 4", "%d", 2), [1; 2])) +