99 lines
3.1 KiB
C++
99 lines
3.1 KiB
C++
#pragma once
|
|
|
|
#include <filesystem> // std::filesystem::path
|
|
#include <fstream> // std::ofstream|ifstream
|
|
#include <iomanip> // std::scientifc|setprecision
|
|
#include <iostream> // std::cout|endl
|
|
#include <limits> // std::numeric_limits
|
|
#include <sstream> // std::istringstream
|
|
#include <string> // std::string
|
|
#include <vector> // std::vector
|
|
|
|
namespace iue::io {
|
|
|
|
/// @brief Writes a numeric values to a file using a csv-format
|
|
/// @param filepath file to be written including the desired extension
|
|
/// @param table table with the rows to be written
|
|
/// @param del delimiter between individual values
|
|
/// @param header informative comment in the output file
|
|
/// @param comments character signalling that a line is a comment (if used as first character of the line )
|
|
inline void savetxt(std::filesystem::path filepath, const std::vector<std::vector<double>>& table, char del = ' ',
|
|
std::string header = "", char comments = '#') {
|
|
|
|
// setup row writer callable
|
|
auto serialize = [&del](const std::vector<double>& row) -> std::string {
|
|
std::ostringstream oss;
|
|
for (auto iter = row.begin(); iter != std::prev(row.end()); ++iter)
|
|
oss << std::scientific << std::setprecision(18) << *iter << del;
|
|
oss << std::scientific << std::setprecision(18) << *std::prev(row.end()); // avoid trailing return
|
|
oss << std::endl;
|
|
return oss.str();
|
|
};
|
|
|
|
// check if data is present
|
|
if (table.empty())
|
|
return;
|
|
|
|
// open file
|
|
std::ofstream stream;
|
|
stream.exceptions(std::ifstream::badbit);
|
|
stream.open(filepath);
|
|
|
|
// write header lines
|
|
if (!header.empty()) {
|
|
std::string line;
|
|
std::istringstream iss(header);
|
|
while (std::getline(iss, line)) {
|
|
stream << comments << ' ' << line << std::endl;
|
|
}
|
|
}
|
|
|
|
// write data
|
|
for (const auto& row : table)
|
|
stream << serialize(row);
|
|
}
|
|
|
|
/// @brief Read numeric values stored in a csv-format
|
|
/// @param filepath input file containing the numeric values
|
|
/// @param del delimiter between individual values
|
|
/// @param comments character signalling that a line is a comment (if used as first character of the line )
|
|
/// @return table which was read
|
|
inline std::vector<std::vector<double>> loadtxt(std::filesystem::path filepath, char del = ' ', char comments = '#') {
|
|
|
|
// setup row parser callable
|
|
auto deserialize = [&del](const std::string& line) -> std::vector<double> {
|
|
std::vector<double> res;
|
|
std::stringstream stream(line);
|
|
std::string item;
|
|
while (std::getline(stream, item, del)) {
|
|
std::stringstream ss(item);
|
|
ss.exceptions(std::ios::failbit);
|
|
auto value = std::numeric_limits<double>::quiet_NaN();
|
|
ss >> value;
|
|
res.push_back(value);
|
|
}
|
|
return res;
|
|
};
|
|
|
|
// setup table
|
|
std::vector<std::vector<double>> table;
|
|
|
|
// open file
|
|
std::ifstream stream;
|
|
stream.exceptions(std::ifstream::badbit);
|
|
stream.open(filepath);
|
|
|
|
// read from stream row-by-row
|
|
std::string line;
|
|
|
|
// read line to row vectors
|
|
while (std::getline(stream, line)) {
|
|
if (line.front() == comments)
|
|
continue;
|
|
table.push_back(deserialize(line));
|
|
}
|
|
|
|
return table;
|
|
}
|
|
|
|
} // namespace iue::io
|