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
std::string file = args(0).string_value();
46
std::string _sep = (args.length() > 1) ? args(1).string_value() : ",";
47
if (_sep.length() != 1) {
48
error("only on charactere need as separator\n");
49
return octave_value();
53
std::string _prot = (args.length() > 2) ? args(2).string_value() : "\"";
54
if (_prot.length() != 1) {
55
error("only on charactere need as protector\n");
56
return octave_value();
61
std::ifstream fd(file.c_str());
63
error("cannot read %s\n", file.c_str());
64
return octave_value();
66
fd.seekg (0, std::ios::end);
67
long fdend = fd.tellg();
68
fd.seekg (0, std::ios::beg);
71
char line[MAXSTRINGLENGTH];
72
std::string str, word;
77
fd.getline(line, MAXSTRINGLENGTH);
81
fd.getline(line, MAXSTRINGLENGTH);
85
/* Parse first to get number of columns */
87
for (int i=0, len=str.length(); i<=len; i++)
88
if (((i==len) || (str[i] == sep)) && (!inside))
90
else if ((inside) && (str[i]==prot) && ((i<len) && (str[i+1]==prot)))
92
else if (str[i] == prot)
95
/* Read all the file to get number of rows */
97
while (fd.tellg() < fdend) {
98
fd.getline(line, MAXSTRINGLENGTH);
101
fd.getline(line, MAXSTRINGLENGTH);
107
fd.seekg (0, std::ios::beg);
109
error("cannot reread %s\n", file.c_str());
110
return octave_value();
113
/* Read all the file until the end */
114
Cell c(nbrows, nbcolumns);
115
for (int i=0; i<nbrows; i++) {
119
fd.getline(line, MAXSTRINGLENGTH);
123
fd.getline(line, MAXSTRINGLENGTH);
127
/* Explode a line into a sub cell */
131
for (int k=0, len=str.length(); k<=len; k++) {
132
if (((k==len) || (str[k] == sep)) && (!inside)) {
134
/* Check number of columns */
135
if (j == nbcolumns) {
137
error("incorrect CSV file, line %d too long\n", i+1);
138
return octave_value();
141
/* Check if scalar */
142
const char *word_str=word.c_str();
144
double val = strtod (word_str, &err);
146
/* Store into the cell */
147
c(i, j++) = ((word == "") || (err != word_str+word.length())) ?
148
octave_value(word) : octave_value(val);
151
else if ((inside) && (str[k]==prot) && ((k<len) && (str[k+1]==prot))) {
153
/* Insisde a string */
157
else if (str[k] == prot)
164
/* Check number of columns */
165
if (j != nbcolumns) {
167
error("incorrect CSV file, line %d too short\n", i+1);
168
return octave_value();
175
return octave_value(c);