Arcane  4.2.3.0
Developer documentation
Loading...
Searching...
No Matches
SimpleCsvReaderWriter.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* SimpleCsvReaderWriter.cc (C) 2000-2026 */
9/* */
10/* Class allowing reading and writing a file in CSV format. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/SimpleCsvReaderWriter.h"
15
16#include "arccore/base/Directory.h"
17#include "arcane/utils/Iostream.h"
18
19#include <limits>
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
24namespace Arcane
25{
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
31writeTable(const Directory& dst, const String& file_name)
32{
33 std::ofstream ofile((dst.file(file_name) + "." + fileType()).localstr());
34 if (ofile.fail())
35 return false;
36
37 _print(ofile);
38
39 ofile.close();
40 return true;
41}
42
44readTable(const Directory& src, const String& file_name)
45{
47
48 std::ifstream stream;
49
50 // If there is no file, we return false.
51 if (!_openFile(stream, src, file_name + "." + fileType())) {
52 return false;
53 }
54
55 std::string line;
56
57 // If there is no first line, we stop here.
58 // A file written by SimpleCsvOutput always has at least one line.
59 if (!std::getline(stream, line)) {
60 _closeFile(stream);
61 return false;
62 }
63
64 // Otherwise, we have the header line, containing the column names
65 // (and the table name).
66 String ligne(line);
67
68 {
70 ligne.split(tmp, m_separator);
71
72 if (tmp.size() == 0) {
73 _closeFile(stream);
74 return false;
75 }
76
77 m_simple_table_internal->m_table_name = tmp[0];
78 m_simple_table_internal->m_column_names = tmp.subConstView(1, tmp.size());
79 }
80
81 // If there are no other lines, it means there are only empty columns
82 // (or no columns) and no lines.
83 if (!std::getline(stream, line)) {
84 _closeFile(stream);
85 return true;
86 }
87
88 // Now that we have the number of columns, we can define dimension 2
89 // of the values array.
90 m_simple_table_internal->m_values.resize(1, m_simple_table_internal->m_column_names.size());
91
92 Integer compt_line = 0;
93
94 do {
95 // We don't know the number of lines in advance, so we must resize
96 // each time.
97 m_simple_table_internal->m_values.resize(compt_line + 1);
98
99 // We split the retrieved line.
100 StringUniqueArray splitted_line;
101 String ligne(line);
102 ligne.split(splitted_line, m_separator);
103
104 // If there is an empty line, we skip it.
105 if (splitted_line.size() == 0) {
106 continue;
107 }
108
109 // If the number of columns in the line does not match the number of
110 // column names, there is an error in the file.
111 if (splitted_line.size() != m_simple_table_internal->m_column_names.size() + 1) {
112 _closeFile(stream);
113 return false;
114 }
115
116 // The first element is the row name.
117 m_simple_table_internal->m_row_names.add(splitted_line[0]);
118
119 // The other elements are Reals.
120 for (Integer i = 1; i < splitted_line.size(); i++) {
121 std::string std_string = splitted_line[i].localstr();
122 std::size_t pos_comma = std_string.find(',');
123
124 if (pos_comma != std::string::npos) {
125 std_string[pos_comma] = '.';
126 }
127
128 m_simple_table_internal->m_values[compt_line][i - 1] = std::stod(std_string);
129 }
130
131 compt_line++;
132 } while (std::getline(stream, line));
133
134 _closeFile(stream);
135
136 // We haven't saved the row/column sizes so we set the max size
137 // for each row/column.
138 m_simple_table_internal->m_row_sizes.resize(m_simple_table_internal->m_row_names.size());
139 m_simple_table_internal->m_row_sizes.fill(m_simple_table_internal->m_values.dim2Size());
140
141 m_simple_table_internal->m_column_sizes.resize(m_simple_table_internal->m_column_names.size());
142 m_simple_table_internal->m_column_sizes.fill(m_simple_table_internal->m_values.dim1Size());
143
144 return true;
145}
146
149{
150 m_simple_table_internal->clear();
151}
152
154print()
155{
156 _print(std::cout);
157}
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
163precision()
164{
165 return m_precision_print;
166}
167
170{
171 if (precision < 1)
172 m_precision_print = 1;
173 else if (precision > (std::numeric_limits<Real>::max_digits10))
174 m_precision_print = (std::numeric_limits<Real>::max_digits10);
175 else
176 m_precision_print = precision;
177}
178
180isFixed()
181{
182 return m_is_fixed_print;
183}
184
186setFixed(bool fixed)
187{
188 m_is_fixed_print = fixed;
189}
190
193{
194 return m_scientific_notation;
195}
196
198setForcedToUseScientificNotation(bool use_scientific)
199{
200 m_scientific_notation = use_scientific;
201}
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
207internal()
208{
209 return m_simple_table_internal;
210}
211
213setInternal(const Ref<SimpleTableInternal>& simple_table_internal)
214{
215 if (simple_table_internal.isNull())
216 ARCANE_FATAL("The reference passed as a parameter is Null.");
217 m_simple_table_internal = simple_table_internal;
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
223bool SimpleCsvReaderWriter::
224_openFile(std::ifstream& stream, Directory directory, const String& file)
225{
226 stream.open(directory.file(file).localstr(), std::ifstream::in);
227 return stream.good();
228}
229
230void SimpleCsvReaderWriter::
231_closeFile(std::ifstream& stream)
232{
233 stream.close();
234}
235
236void SimpleCsvReaderWriter::
237_print(std::ostream& stream)
238{
239 // We save the stream info to restore it at the end.
240 std::ios_base::fmtflags save_flags = stream.flags();
241 std::streamsize save_prec = stream.precision();
242
243 if (m_is_fixed_print) {
244 stream << std::setiosflags(std::ios::fixed);
245 }
246 if (m_scientific_notation) {
247 stream << std::scientific;
248 }
249 stream << std::setprecision(m_precision_print);
250
251 stream << m_simple_table_internal->m_table_name << m_separator;
252
253 for (Integer j = 0; j < m_simple_table_internal->m_column_names.size(); j++) {
254 stream << m_simple_table_internal->m_column_names[j] << m_separator;
255 }
256 stream << std::endl;
257
258 for (Integer i = 0; i < m_simple_table_internal->m_values.dim1Size(); i++) {
259 stream << m_simple_table_internal->m_row_names[i] << m_separator;
260 ConstArrayView<Real> view = m_simple_table_internal->m_values[i];
261 for (Integer j = 0; j < m_simple_table_internal->m_values.dim2Size(); j++) {
262 stream << view[j] << m_separator;
263 }
264 stream << std::endl;
265 }
266
267 stream.flags(save_flags);
268 stream.precision(save_prec);
269}
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
273
274} // End namespace Arcane
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sub-view starting from element abegin and containing asize elements.
String file(const String &file_name) const override
Returns the full path of the file file_name in the directory.
Definition Directory.cc:120
bool isNull() const
Indicates if the counter references a non-null instance.
Reference to an instance.
void setFixed(bool fixed) override
Method allowing setting or unsetting the 'std::fixed' flag.
void setInternal(const Ref< SimpleTableInternal > &simple_table_internal) override
Method allowing setting a reference to a SimpleTableInternal.
bool isForcedToUseScientificNotation() override
Method allowing checking if the 'std::scientific' flag is active or not for writing values.
void clearInternal() override
Method allowing clearing the content of the SimpleTableInternal object.
void setForcedToUseScientificNotation(bool use_scientific) override
Method allowing setting or unsetting the 'std::scientific' flag.
bool readTable(const Directory &src, const String &file_name) override
Method allowing reading a file containing a simple table.
String fileType() override
Method allowing retrieval of the file type that will be written by the implementation....
void print() override
Method allowing writing the table to the standard output.
bool isFixed() override
Method allowing checking if the 'std::fixed' flag is active or not for writing values.
Ref< SimpleTableInternal > internal() override
Method allowing retrieval of a reference to the SimpleTableInternal object used.
bool writeTable(const Directory &dst, const String &file_name) override
Method allowing writing a simple table to a file.
void setPrecision(Integer precision) override
Method allowing modification of the print precision.
Integer precision() override
Method allowing retrieval of the precision currently used for writing values.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
void split(StringContainer &str_array, char c) const
Splits the string based on the character c.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
UniqueArray< String > StringUniqueArray
Dynamic 1D array of strings.
Definition UtilsTypes.h:353