GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
dlmread.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2008-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 // Adapted from previous version of dlmread.occ as authored by Kai
27 // Habel, but core code has been completely re-written.
28 
29 #if defined (HAVE_CONFIG_H)
30 # include "config.h"
31 #endif
32 
33 #include <cmath>
34 #include <cctype>
35 #include <fstream>
36 #include <limits>
37 
38 #include "file-ops.h"
39 #include "lo-ieee.h"
40 #include "lo-sysdep.h"
41 
42 #include "defun.h"
43 #include "interpreter.h"
44 #include "oct-stream.h"
45 #include "error.h"
46 #include "ovl.h"
47 #include "utils.h"
48 
51 
52 static const double idx_max_dbl = double (idx_max);
53 
54 static bool
55 read_cell_spec (std::istream& is, octave_idx_type& row, octave_idx_type& col)
56 {
57  bool stat = false;
58 
59  if (is.peek () == std::istream::traits_type::eof ())
60  stat = true;
61  else
62  {
63  if (::isalpha (is.peek ()))
64  {
65  col = 0;
66  while (is && ::isalpha (is.peek ()))
67  {
68  char ch = is.get ();
69  col *= 26;
70  if (ch >= 'a')
71  col += ch - 'a' + 1;
72  else
73  col += ch - 'A' + 1;
74  }
75  col--;
76 
77  if (is)
78  {
79  is >> row;
80  row--;
81  if (is)
82  stat = true;
83  }
84  }
85  }
86 
87  return stat;
88 }
89 
90 static bool
91 parse_range_spec (const octave_value& range_spec,
94 {
95  bool stat = true;
96 
97  if (range_spec.is_string ())
98  {
99  std::istringstream is (range_spec.string_value ());
100  char ch = is.peek ();
101 
102  if (ch == '.' || ch == ':')
103  {
104  rlo = 0;
105  clo = 0;
106  ch = is.get ();
107  if (ch == '.')
108  {
109  ch = is.get ();
110  if (ch != '.')
111  stat = false;
112  }
113  }
114  else
115  {
116  stat = read_cell_spec (is, rlo, clo);
117 
118  if (stat)
119  {
120  ch = is.peek ();
121 
122  if (ch == '.' || ch == ':')
123  {
124  ch = is.get ();
125  if (ch == '.')
126  {
127  ch = is.get ();
128  if (! is || ch != '.')
129  stat = false;
130  }
131 
132  rup = idx_max;
133  cup = idx_max;
134  }
135  else
136  {
137  rup = rlo;
138  cup = clo;
139  if (! is || ! is.eof ())
140  stat = false;
141  }
142  }
143  }
144 
145  if (stat && is && ! is.eof ())
146  stat = read_cell_spec (is, rup, cup);
147 
148  if (! is || ! is.eof ())
149  stat = false;
150  }
151  else if (range_spec.is_real_matrix () && range_spec.numel () == 4)
152  {
153  NDArray range (range_spec.array_value ());
154  if (range.any_element_is_nan ())
155  error ("dlmread: NaN is not a valid row or column specifier");
156 
157  // double --> unsigned int avoiding any overflow
158  rlo = static_cast<octave_idx_type> (std::min (range(0), idx_max_dbl));
159  clo = static_cast<octave_idx_type> (std::min (range(1), idx_max_dbl));
160  rup = static_cast<octave_idx_type> (std::min (range(2), idx_max_dbl));
161  cup = static_cast<octave_idx_type> (std::min (range(3), idx_max_dbl));
162  }
163  else
164  stat = false;
165 
166  return stat;
167 }
168 
169 DEFMETHOD (dlmread, interp, args, ,
170  doc: /* -*- texinfo -*-
171 @deftypefn {} {@var{data} =} dlmread (@var{file})
172 @deftypefnx {} {@var{data} =} dlmread (@var{file}, @var{sep})
173 @deftypefnx {} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{r0}, @var{c0})
174 @deftypefnx {} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{range})
175 @deftypefnx {} {@var{data} =} dlmread (@dots{}, "emptyvalue", @var{EMPTYVAL})
176 Read numeric data from the text file @var{file} which uses the delimiter
177 @var{sep} between data values.
178 
179 If @var{sep} is not defined the separator between fields is determined from
180 the file itself.
181 
182 The optional scalar arguments @var{r0} and @var{c0} define the starting row
183 and column of the data to be read. These values are indexed from zero,
184 i.e., the first data row corresponds to an index of zero.
185 
186 The @var{range} parameter specifies exactly which data elements are read.
187 The first form of the parameter is a 4-element vector containing the upper
188 left and lower right corners @code{[@var{R0},@var{C0},@var{R1},@var{C1}]}
189 where the indices are zero-based. To specify the last column---the equivalent
190 of @code{end} when indexing---use the specifier @code{Inf}. Alternatively, a
191 spreadsheet style form such as @qcode{"A2..Q15"} or @qcode{"T1:AA5"} can be
192 used. The lowest alphabetical index @qcode{'A'} refers to the first column.
193 The lowest row index is 1.
194 
195 @var{file} should be a filename or a file id given by @code{fopen}. In the
196 latter case, the file is read until end of file is reached.
197 
198 The @qcode{"emptyvalue"} option may be used to specify the value used to
199 fill empty fields. The default is zero. Note that any non-numeric values,
200 such as text, are also replaced by the @qcode{"emptyvalue"}.
201 @seealso{csvread, textscan, dlmwrite}
202 @end deftypefn */)
203 {
204  int nargin = args.length ();
205 
206  double empty_value = 0.0;
207 
208  if (nargin > 2 && args(nargin-2).is_string ()
209  && args(nargin-2).string_value () == "emptyvalue")
210  {
211  empty_value = args(nargin-1).double_value ();
212 
213  nargin -= 2;
214  }
215 
216  if (nargin < 1 || nargin > 4)
217  print_usage ();
218 
219  std::istream *input = nullptr;
220  std::ifstream input_file;
221 
222  if (args(0).is_string ())
223  {
224  // Filename.
225  std::string fname (args(0).string_value ());
226 
227  std::string tname = octave::sys::file_ops::tilde_expand (fname);
228 
229  tname = octave::find_data_file_in_load_path ("dlmread", tname);
230 
231 #if defined (OCTAVE_USE_WINDOWS_API)
232  std::wstring wname = octave::sys::u8_to_wstring (tname);
233  input_file.open (wname.c_str (), std::ios::in);
234 #else
235  input_file.open (tname.c_str (), std::ios::in);
236 #endif
237 
238  if (! input_file)
239  error ("dlmread: unable to open file '%s'", fname.c_str ());
240 
241  input = &input_file;
242  }
243  else if (args(0).is_scalar_type ())
244  {
245  octave::stream_list& streams = interp.get_stream_list ();
246 
247  octave::stream is = streams.lookup (args(0), "dlmread");
248 
249  input = is.input_stream ();
250 
251  if (! input)
252  error ("dlmread: stream FILE not open for input");
253  }
254  else
255  error ("dlmread: FILE argument must be a string or file id");
256 
257  // Set default separator.
258  std::string sep;
259  if (nargin > 1)
260  {
261  if (args(1).is_sq_string ())
262  sep = octave::do_string_escapes (args(1).string_value ());
263  else
264  sep = args(1).string_value ();
265  }
266 
267  // Take a subset if a range was given.
268  octave_idx_type r0 = 0;
269  octave_idx_type c0 = 0;
272  if (nargin > 2)
273  {
274  if (nargin == 3)
275  {
276  if (! parse_range_spec (args(2), r0, c0, r1, c1))
277  error ("dlmread: error parsing RANGE");
278  }
279  else if (nargin == 4)
280  {
281  r0 = args(2).idx_type_value ();
282  c0 = args(3).idx_type_value ();
283  }
284 
285  if (r0 < 0 || c0 < 0)
286  error ("dlmread: left (R0) and top (C0) must be positive");
287 
288  // Short-circuit and return if range is empty
289  if (r1 < r0 || c1 < c0)
290  return ovl (Matrix (0,0));
291  }
292 
293  octave_idx_type i = 0;
294  octave_idx_type j = 0;
295  octave_idx_type r = 1;
296  octave_idx_type c = 1;
297  // Start with a reasonable size to avoid constant resizing of matrix.
298  octave_idx_type rmax = 32;
299  octave_idx_type cmax = 0;
300 
301  Matrix rdata (rmax, cmax, empty_value);
302  ComplexMatrix cdata;
303 
304  bool iscmplx = false;
305  bool sep_is_wspace = (sep.find_first_of (" \t") != std::string::npos);
306  bool auto_sep_is_wspace = false;
307 
308  std::string line;
309 
310  // Skip the r0 leading lines
311  octave_idx_type rcnt = r0;
312  while (rcnt > 0 && getline (*input, line))
313  rcnt--;
314 
315  if (rcnt > 0)
316  return ovl (Matrix (0,0)); // Not enough lines in file to satisfy RANGE
317  else
318  r1 -= r0;
319 
320  std::istringstream tmp_stream;
321 
322  // Read the data one field at a time, growing the data matrix as needed.
323  while (getline (*input, line))
324  {
325  // Skip blank lines for compatibility.
326  if ((! sep_is_wspace || auto_sep_is_wspace)
327  && line.find_first_not_of (" \t") == std::string::npos)
328  continue;
329 
330  // Infer separator from file if delimiter is blank.
331  if (sep.empty ())
332  {
333  // Skip leading whitespace.
334  size_t pos1 = line.find_first_not_of (" \t");
335 
336  // For Matlab compatibility, blank delimiter should
337  // correspond to whitespace (space and tab).
338  size_t n = line.find_first_of (",:; \t", pos1);
339  if (n == std::string::npos)
340  {
341  sep = " \t";
342  auto_sep_is_wspace = true;
343  }
344  else
345  {
346  char ch = line.at (n);
347 
348  switch (line.at (n))
349  {
350  case ' ':
351  case '\t':
352  sep = " \t";
353  auto_sep_is_wspace = true;
354  break;
355 
356  default:
357  sep = ch;
358  break;
359  }
360  }
361  }
362 
363  // Estimate the number of columns from first line of data.
364  if (cmax == 0)
365  {
366  size_t pos1, pos2;
367  if (auto_sep_is_wspace)
368  pos1 = line.find_first_not_of (" \t");
369  else
370  pos1 = 0;
371 
372  do
373  {
374  pos2 = line.find_first_of (sep, pos1);
375 
376  if (auto_sep_is_wspace && pos2 != std::string::npos)
377  {
378  // Treat consecutive separators as one.
379  pos2 = line.find_first_not_of (sep, pos2);
380  if (pos2 != std::string::npos)
381  pos2 -= 1;
382  }
383 
384  // Separator followed by EOL doesn't generate extra column
385  if (pos2 != std::string::npos)
386  cmax++;
387 
388  pos1 = pos2 + 1;
389  }
390  while (pos2 != std::string::npos);
391 
392  // FIXME: Should always be the case that iscmplx == false.
393  // Flag is initialized that way and no data has been read.
394  if (iscmplx)
395  cdata.resize (rmax, cmax, empty_value);
396  else
397  rdata.resize (rmax, cmax, empty_value);
398  }
399 
400  r = (r > i + 1 ? r : i + 1);
401  j = 0;
402 
403  size_t pos1, pos2;
404  if (auto_sep_is_wspace)
405  pos1 = line.find_first_not_of (" \t"); // Skip leading whitespace.
406  else
407  pos1 = 0;
408 
409  do
410  {
411  octave_quit ();
412 
413  pos2 = line.find_first_of (sep, pos1);
414  std::string str = line.substr (pos1, pos2 - pos1);
415 
416  if (auto_sep_is_wspace && pos2 != std::string::npos)
417  {
418  // Treat consecutive separators as one.
419  pos2 = line.find_first_not_of (sep, pos2);
420  if (pos2 != std::string::npos)
421  pos2 -= 1;
422  else
423  pos2 = line.length () - 1;
424  }
425 
426  // Separator followed by EOL doesn't generate extra column
427  if (pos2 == std::string::npos && str.empty ())
428  break;
429 
430  c = (c > j + 1 ? c : j + 1);
431  if (r > rmax || c > cmax)
432  {
433  // Use resize_and_fill for the case of unequal length rows.
434  // Keep rmax a power of 2.
435  rmax = std::max (2*(r-1), rmax);
436  cmax = std::max (c, cmax);
437  if (iscmplx)
438  cdata.resize (rmax, cmax, empty_value);
439  else
440  rdata.resize (rmax, cmax, empty_value);
441  }
442 
443  tmp_stream.str (str);
444  tmp_stream.clear ();
445 
446  double x = octave_read_double (tmp_stream);
447  if (tmp_stream)
448  {
449  if (tmp_stream.eof ())
450  {
451  if (iscmplx)
452  cdata(i,j++) = x;
453  else
454  rdata(i,j++) = x;
455  }
456  else
457  {
458  int next_char = tmp_stream.peek ();
459  if (next_char == 'i' || next_char == 'j'
460  || next_char == 'I' || next_char == 'J')
461  {
462  // Process pure imaginary numbers.
463  tmp_stream.get ();
464  next_char = tmp_stream.peek ();
465  if (next_char == std::istringstream::traits_type::eof ())
466  {
467  if (! iscmplx)
468  {
469  iscmplx = true;
470  cdata = ComplexMatrix (rdata);
471  }
472 
473  cdata(i,j++) = Complex (0, x);
474  }
475  else
476  {
477  // Parsing failed, <number>i|j<extra text>
478  j++; // Leave data initialized to empty_value
479  }
480  }
481  else if (std::isalpha (next_char) && ! std::isfinite (x))
482  {
483  // Parsing failed, <Inf|NA|NaN><extra text>
484  j++; // Leave data initialized to empty_value
485  }
486  else
487  {
488  double y = octave_read_double (tmp_stream);
489 
490  if (! iscmplx && y != 0.0)
491  {
492  iscmplx = true;
493  cdata = ComplexMatrix (rdata);
494  }
495 
496  if (iscmplx)
497  cdata(i,j++) = Complex (x, y);
498  else
499  rdata(i,j++) = x;
500  }
501  }
502  }
503  else
504  {
505  // octave_read_double() parsing failed
506  j++; // Leave data initialized to empty_value
507  }
508 
509  pos1 = pos2 + 1;
510  }
511  while (pos2 != std::string::npos);
512 
513  if (i == r1)
514  break; // Stop early if the desired range has been read.
515 
516  i++;
517  }
518 
519  // Clip selection indices to actual size of data
520  if (r1 >= r)
521  r1 = r - 1;
522  if (c1 >= c)
523  c1 = c - 1;
524 
525  if (iscmplx)
526  {
527  if ((i == 0 && j == 0) || (c0 > c1))
528  return ovl (ComplexMatrix (0,0));
529 
530  cdata = cdata.extract (0, c0, r1, c1);
531  return ovl (cdata);
532  }
533  else
534  {
535  if ((i == 0 && j == 0) || (c0 > c1))
536  return ovl (Matrix (0,0));
537 
538  rdata = rdata.extract (0, c0, r1, c1);
539  return ovl (rdata);
540  }
541 }
542 
543 /*
544 %!test
545 %! file = tempname ();
546 %! unwind_protect
547 %! fid = fopen (file, "wt");
548 %! fwrite (fid, "1, 2, 3\n4, 5, 6\n7, 8, 9\n10, 11, 12");
549 %! fclose (fid);
550 %!
551 %! assert (dlmread (file), [1, 2, 3; 4, 5, 6; 7, 8, 9;10, 11, 12]);
552 %! assert (dlmread (file, ","), [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12]);
553 %! assert (dlmread (file, ",", [1, 0, 2, 1]), [4, 5; 7, 8]);
554 %! assert (dlmread (file, ",", "B1..C2"), [2, 3; 5, 6]);
555 %! assert (dlmread (file, ",", "B1:C2"), [2, 3; 5, 6]);
556 %! assert (dlmread (file, ",", "..C2"), [1, 2, 3; 4, 5, 6]);
557 %! assert (dlmread (file, ",", 0, 1), [2, 3; 5, 6; 8, 9; 11, 12]);
558 %! assert (dlmread (file, ",", "B1.."), [2, 3; 5, 6; 8, 9; 11, 12]);
559 %! assert (dlmread (file, ",", 10, 0), []);
560 %! assert (dlmread (file, ",", 0, 10), []);
561 %! fail ('dlmread (file, ",", [0 1])', "error parsing RANGE");
562 %! unwind_protect_cleanup
563 %! unlink (file);
564 %! end_unwind_protect
565 
566 %!testif ; ! ismac ()
567 %! file = tempname ();
568 %! unwind_protect
569 %! fid = fopen (file, "wt");
570 %! fwrite (fid, "1, 2, 3\n4+4i, 5, 6\n7, 8, 9\n10, 11, 12");
571 %! fclose (fid);
572 %!
573 %! assert (dlmread (file), [1, 2, 3; 4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
574 %! assert (dlmread (file, ","), [1,2,3; 4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
575 %! assert (dlmread (file, ",", [1, 0, 2, 1]), [4 + 4i, 5; 7, 8]);
576 %! assert (dlmread (file, ",", "A2..B3"), [4 + 4i, 5; 7, 8]);
577 %! assert (dlmread (file, ",", "A2:B3"), [4 + 4i, 5; 7, 8]);
578 %! assert (dlmread (file, ",", "..B3"), [1, 2; 4 + 4i, 5; 7, 8]);
579 %! assert (dlmread (file, ",", 1, 0), [4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
580 %! assert (dlmread (file, ",", "A2.."), [4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
581 %! assert (dlmread (file, ",", 10, 0), []);
582 %! assert (dlmread (file, ",", 0, 10), []);
583 %! unwind_protect_cleanup
584 %! unlink (file);
585 %! end_unwind_protect
586 
587 %!xtest <47413>
588 %! ## Same test code as above, but intended only for test statistics on Mac.
589 %! if (! ismac ()), return; endif
590 %! file = tempname ();
591 %! unwind_protect
592 %! fid = fopen (file, "wt");
593 %! fwrite (fid, "1, 2, 3\n4+4i, 5, 6\n7, 8, 9\n10, 11, 12");
594 %! fclose (fid);
595 %!
596 %! assert (dlmread (file), [1, 2, 3; 4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
597 %! assert (dlmread (file, ","), [1,2,3; 4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
598 %! assert (dlmread (file, ",", [1, 0, 2, 1]), [4 + 4i, 5; 7, 8]);
599 %! assert (dlmread (file, ",", "A2..B3"), [4 + 4i, 5; 7, 8]);
600 %! assert (dlmread (file, ",", "A2:B3"), [4 + 4i, 5; 7, 8]);
601 %! assert (dlmread (file, ",", "..B3"), [1, 2; 4 + 4i, 5; 7, 8]);
602 %! assert (dlmread (file, ",", 1, 0), [4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
603 %! assert (dlmread (file, ",", "A2.."), [4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
604 %! assert (dlmread (file, ",", 10, 0), []);
605 %! assert (dlmread (file, ",", 0, 10), []);
606 %! unwind_protect_cleanup
607 %! unlink (file);
608 %! end_unwind_protect
609 
610 %!test <*42025>
611 %! file = tempname ();
612 %! unwind_protect
613 %! fid = fopen (file, "wt");
614 %! fwrite (fid, " \n 1 2\n11 22\n ");
615 %! fclose (fid);
616 %!
617 %! assert (dlmread (file), [1, 2; 11, 22]);
618 %! assert (dlmread (file, " "), [ 0, 0, 0, 0
619 %! 0, 1, 2, 0
620 %! 11, 22, 0, 0
621 %! 0, 0, 0, 0]);
622 %! unwind_protect_cleanup
623 %! unlink (file);
624 %! end_unwind_protect
625 
626 %!testif ; ! ismac () <*50589>
627 %! file = tempname ();
628 %! unwind_protect
629 %! fid = fopen (file, "wt");
630 %! fwrite (fid, "1;2;3\n");
631 %! fwrite (fid, "1i;2I;3j;4J\n");
632 %! fwrite (fid, "4;5;6\n");
633 %! fwrite (fid, "-4i;+5I;-6j;+7J\n");
634 %! fclose (fid);
635 %!
636 %! assert (dlmread (file), [1, 2, 3, 0; 1i, 2i, 3i, 4i;
637 %! 4, 5, 6, 0; -4i, 5i, -6i, 7i]);
638 %! assert (dlmread (file, "", [0 0 0 3]), [1, 2, 3]);
639 %! assert (dlmread (file, "", [1 0 1 3]), [1i, 2i, 3i, 4i]);
640 %! unwind_protect_cleanup
641 %! unlink (file);
642 %! end_unwind_protect
643 
644 %!xtest <47413>
645 %! ## Same test code as above, but intended only for test statistics on Mac.
646 %! if (! ismac ()), return; endif
647 %! file = tempname ();
648 %! unwind_protect
649 %! fid = fopen (file, "wt");
650 %! fwrite (fid, "1;2;3\n");
651 %! fwrite (fid, "1i;2I;3j;4J\n");
652 %! fwrite (fid, "4;5;6\n");
653 %! fwrite (fid, "-4i;+5I;-6j;+7J\n");
654 %! fclose (fid);
655 %!
656 %! assert (dlmread (file), [1, 2, 3, 0; 1i, 2i, 3i, 4i;
657 %! 4, 5, 6, 0; -4i, 5i, -6i, 7i]);
658 %! assert (dlmread (file, "", [0 0 0 3]), [1, 2, 3]);
659 %! assert (dlmread (file, "", [1 0 1 3]), [1i, 2i, 3i, 4i]);
660 %! unwind_protect_cleanup
661 %! unlink (file);
662 %! end_unwind_protect
663 
664 ## NA was not properly read from a file
665 %!test
666 %! file = tempname ();
667 %! unwind_protect
668 %! fid = fopen (file, "wt");
669 %! fwrite (fid, "1,NA,3");
670 %! fclose (fid);
671 %!
672 %! assert (dlmread (file), [1, NA, 3]);
673 %! unwind_protect_cleanup
674 %! unlink (file);
675 %! end_unwind_protect
676 
677 ## "Name" was read as NA rather than parse error
678 %!test <*54029>
679 %! file = tempname ();
680 %! unwind_protect
681 %! fid = fopen (file, "wt");
682 %! fwrite (fid, "NaNe,bNa,Name,c\n1,NaN,3,Inftest\n-Inf,6,NA,8");
683 %! fclose (fid);
684 %!
685 %! assert (dlmread (file), [0, 0, 0, 0; 1, NaN, 3, 0; -Inf, 6, NA, 8]);
686 %! unwind_protect_cleanup
687 %! unlink (file);
688 %! end_unwind_protect
689 
690 ## Infinity incorrectly changed matrix to complex, rather than parse error
691 %!test
692 %! file = tempname ();
693 %! unwind_protect
694 %! fid = fopen (file, "wt");
695 %! fwrite (fid, "1,Infinity,3");
696 %! fclose (fid);
697 %!
698 %! assert (dlmread (file), [1, 0, 3]);
699 %! unwind_protect_cleanup
700 %! unlink (file);
701 %! end_unwind_protect
702 
703 ## Purely complex numbers with trailing garbage produced complex matrix
704 %!test
705 %! file = tempname ();
706 %! unwind_protect
707 %! fid = fopen (file, "wt");
708 %! fwrite (fid, "1,2jack,3");
709 %! fclose (fid);
710 %!
711 %! assert (dlmread (file), [1, 0, 3]);
712 %! unwind_protect_cleanup
713 %! unlink (file);
714 %! end_unwind_protect
715 
716 */
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
ComplexMatrix extract(octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
Definition: CMatrix.cc:683
void resize(octave_idx_type nr, octave_idx_type nc, const Complex &rfv=Complex(0))
Definition: CMatrix.h:190
Definition: dMatrix.h:42
Matrix extract(octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
Definition: dMatrix.cc:397
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
Definition: dMatrix.h:151
bool any_element_is_nan(void) const
Definition: dNDArray.cc:318
stream lookup(int fid, const std::string &who="") const
Definition: oct-stream.cc:7427
std::istream * input_stream(void)
Definition: oct-stream.h:380
octave_idx_type numel(void) const
Definition: ov.h:518
bool is_string(void) const
Definition: ov.h:593
std::string string_value(bool force=false) const
Definition: ov.h:927
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:812
bool is_real_matrix(void) const
Definition: ov.h:569
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:138
static bool read_cell_spec(std::istream &is, octave_idx_type &row, octave_idx_type &col)
Definition: dlmread.cc:55
static bool parse_range_spec(const octave_value &range_spec, octave_idx_type &rlo, octave_idx_type &clo, octave_idx_type &rup, octave_idx_type &cup)
Definition: dlmread.cc:91
static const double idx_max_dbl
Definition: dlmread.cc:52
static const octave_idx_type idx_max
Definition: dlmread.cc:50
void error(const char *fmt,...)
Definition: error.cc:968
F77_RET_T const F77_DBLE * x
double octave_read_double(std::istream &is)
Definition: lo-utils.h:104
octave_idx_type n
Definition: mx-inlines.cc:753
T * r
Definition: mx-inlines.cc:773
bool isfinite(double x)
Definition: lo-mappers.h:192
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:286
std::ifstream ifstream(const std::string &filename, const std::ios::openmode mode)
Definition: lo-sysdep.cc:381
std::wstring u8_to_wstring(const std::string &utf8_string)
Definition: lo-sysdep.cc:468
std::string do_string_escapes(const std::string &s)
Definition: utils.cc:654
std::string find_data_file_in_load_path(const std::string &fcn, const std::string &file, bool require_regular_file)
Definition: utils.cc:553
std::complex< double > Complex
Definition: oct-cmplx.h:33
static int input(yyscan_t yyscanner)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
subroutine stat(x, n, av, var, xmin, xmax)
Definition: tstgmn.for:112