2
* Copyright (C) 2004 Laurent Mazet
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; If not, see <http://www.gnu.org/licenses/>.
24
#include <octave/oct.h>
25
#include <octave/Cell.h>
27
#define MAXSTRINGLENGTH 4096
29
DEFUN_DLD (csv2cell, args, nargout,
31
"@deftypefn {Function File} {@var{c} = } csv2cell (@var{file})\n"
32
"@deftypefnx {Function File} {@var{c} = } csv2cell (@var{file}, @var{sep})\n"
33
"@deftypefnx {Function File} {@var{c} = } csv2cell (@var{file}, @var{sep}, @var{prot})\n"
35
"Read a CSV (Comma Separated Values) file and convert it into a "
37
"@var{sep} changes the character used to separate two fields. By "
38
"default, two fields are expected to be separated by a coma "
39
"(@code{,}). @var{prot} changes the character used to protect a string. "
40
"By default it's a double quote (@code{\"}).\n"
44
const int nargin = args.length ();
45
octave_value_list retval;
48
error ("csv2cell: not enough input arguments");
52
const std::string file = args (0).string_value ();
54
const std::string _sep = (nargin > 1) ? args (1).string_value () : ",";
55
if (_sep.length() != 1)
57
error ("csv2cell: only on charactere need as separator");
62
const std::string _prot = (nargin > 2) ? args (2).string_value () : "\"";
63
if (_prot.length() != 1)
65
error ("csv2cell: only on charactere need as protector");
71
std::ifstream fd (file.c_str ());
74
error ("csv2cell: cannot read %s", file.c_str());
77
fd.seekg (0, std::ios::end);
78
long fdend = fd.tellg ();
79
fd.seekg (0, std::ios::beg);
82
char line [MAXSTRINGLENGTH];
83
std::string str, word;
88
fd.getline (line, MAXSTRINGLENGTH);
93
fd.getline (line, MAXSTRINGLENGTH);
97
/* Parse first to get number of columns */
99
for (int i = 0, len = str.length (); i <= len; i++)
100
if (((i==len) || (str [i] == sep)) && (!inside))
102
else if ((inside) && (str [i] == prot) && ((i < len) && (str [i+1] == prot)))
104
else if (str [i] == prot)
107
/* Read all the file to get number of rows */
109
while (fd.tellg () < fdend)
111
fd.getline (line, MAXSTRINGLENGTH);
115
fd.getline (line, MAXSTRINGLENGTH);
121
fd.seekg (0, std::ios::beg);
124
error ("csv2cell: cannot reread %s", file.c_str ());
128
/* Read all the file until the end */
129
Cell c (nbrows, nbcolumns);
130
for (int i = 0; i < nbrows; i++)
134
fd.getline (line, MAXSTRINGLENGTH);
139
fd.getline (line, MAXSTRINGLENGTH);
143
/* Explode a line into a sub cell */
147
for (int k = 0, len = str.length (); k <= len; k++)
149
if (((k == len) || (str [k] == sep)) && (!inside))
151
/* Check number of columns */
155
error ("csv2cell: incorrect CSV file, line %d too long", i+1);
159
/* Check if scalar */
160
const char *word_str = word.c_str ();
162
double val = strtod (word_str, &err);
164
/* Store into the cell */
165
c (i, j++) = ((word == "") || (err != word_str+word.length())) ?
166
octave_value (word) : octave_value (val);
169
else if ((inside) && (str[k]==prot) && ((k<len) && (str[k+1]==prot)))
171
/* Insisde a string */
175
else if (str[k] == prot)
182
/* Check number of columns */
186
error ("csv2cell: incorrect CSV file, line %d too short", i+1);