From c93535842dd6abf3d1f1d15c7414d7934a593b49 Mon Sep 17 00:00:00 2001 From: rinkk <karsten.rink@ufz.de> Date: Fri, 29 Mar 2019 14:41:46 +0100 Subject: [PATCH] Added method to return column-names to CSV interface --- Applications/FileIO/CsvInterface.cpp | 33 ++++++++++++++++++++++++++++ Applications/FileIO/CsvInterface.h | 5 +++++ Tests/FileIO/TestCsvReader.cpp | 9 ++++++-- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/Applications/FileIO/CsvInterface.cpp b/Applications/FileIO/CsvInterface.cpp index b508181b095..f5850fb3103 100644 --- a/Applications/FileIO/CsvInterface.cpp +++ b/Applications/FileIO/CsvInterface.cpp @@ -22,6 +22,39 @@ namespace FileIO { CsvInterface::CsvInterface() = default; +std::vector<std::string> CsvInterface::getColumnNames(std::string const& fname, + char const delim) +{ + std::ifstream in(fname.c_str()); + + if (!in.is_open()) + { + ERR("CsvInterface::readPoints(): Could not open file %s.", + fname.c_str()); + return std::vector<std::string>(); + } + std::string line; + if (!getline(in, line)) + return {}; + + std::list<std::string> fields; + if (delim != '\n') + fields = BaseLib::splitString(line, delim); + + if (fields.size() < 2) + { + for (char const d : {'\t', ';', ','}) + { + fields = BaseLib::splitString(line, d); + if (fields.size() > 1) + { + break; + } + } + } + return {begin(fields), end(fields)}; +} + int CsvInterface::readPoints(std::string const& fname, char delim, std::vector<GeoLib::Point*> &points) { diff --git a/Applications/FileIO/CsvInterface.h b/Applications/FileIO/CsvInterface.h index b2e0bdd6241..779d7de4a60 100644 --- a/Applications/FileIO/CsvInterface.h +++ b/Applications/FileIO/CsvInterface.h @@ -48,6 +48,11 @@ public: /// Returns the number of vectors currently staged for writing. std::size_t getNArrays() const { return _vec_names.size(); } + /// Returns a vector containing the names of columns in the file (assuming + /// the file *has* a header) + static std::vector<std::string> getColumnNames(std::string const& fname, + char delim); + /// Adds an index vector of size s to the CSV file void addIndexVectorForWriting(std::size_t s); diff --git a/Tests/FileIO/TestCsvReader.cpp b/Tests/FileIO/TestCsvReader.cpp index fd12ecb4dac..2d369857170 100644 --- a/Tests/FileIO/TestCsvReader.cpp +++ b/Tests/FileIO/TestCsvReader.cpp @@ -168,15 +168,20 @@ TEST_F(CsvInterfaceTest, CoordinateOrder) /// Getting single columns TEST_F(CsvInterfaceTest, GetColumn) { + std::vector<std::string> columns = + FileIO::CsvInterface::getColumnNames(_file_name, '\t'); + ASSERT_EQ(7, columns.size()); std::vector<std::string> names; - _result = FileIO::CsvInterface::readColumn<std::string>(_file_name, '\t', names, "name"); + _result = FileIO::CsvInterface::readColumn<std::string>(_file_name, '\t', names, columns[4]); ASSERT_EQ(0, _result); ASSERT_EQ(10, names.size()); + ASSERT_EQ("test_j", names[9]); std::vector<double> values; - _result = FileIO::CsvInterface::readColumn<double>(_file_name, '\t', values, "value_two"); + _result = FileIO::CsvInterface::readColumn<double>(_file_name, '\t', values, columns[6]); ASSERT_EQ(2, _result); ASSERT_EQ(8, values.size()); + ASSERT_NEAR(135, values[1], std::numeric_limits<double>::epsilon()); } /// Dealing with non-existing column -- GitLab