mars_lib 0.1.0.2abe2576fe7f
Modular and Robust Sensor-Fusion
Loading...
Searching...
No Matches
read_csv.h
Go to the documentation of this file.
1// Copyright (C) 2021 Christian Brommer, Control of Networked Systems, University of Klagenfurt, Austria.
2//
3// All rights reserved.
4//
5// This software is licensed under the terms of the BSD-2-Clause-License with
6// no commercial use allowed, the full terms of which are made available
7// in the LICENSE file. No license in patents is granted.
8//
9// You can contact the author at <christian.brommer@ieee.org>
10
11#ifndef READ_CSV_H
12#define READ_CSV_H
13
14#include <algorithm>
15#include <fstream>
16#include <iomanip>
17#include <iostream>
18#include <map>
19#include <sstream>
20#include <string>
21#include <vector>
23
24namespace mars
25{
26using CsvDataType = std::map<std::string, std::vector<double>>;
27using HeaderMapType = std::map<int, std::string>;
28
30{
31 char delim{ ',' };
33
34public:
35 ReadCsv(CsvDataType* csv_data, const std::string& file_path, char delim_ = ',') : delim(delim_)
36 {
37 if (!mars::filesystem::IsFile(file_path))
38 {
39 std::cout << "ReadCsv(): [Warning] File " << file_path << " does not exist." << std::endl;
40 exit(EXIT_FAILURE);
41 }
42
43 file_.open(file_path);
44
45 // Check for header
46 const int first_value_row = check_for_header();
47
48 // Initialize CSV data type
49 const int rows = get_rows();
50
51 if (first_value_row < 1)
52 {
53 std::cout << "ReadCsv():Error: No header in CSV file" << std::endl;
54 exit(EXIT_FAILURE);
55 }
56
57 header_map = get_header(first_value_row - 1);
58
59 // Set line counter to first valued row
60 if (first_value_row > 0)
61 {
62 set_line_couter_of_file(first_value_row);
63 }
64
65 CsvDataType csv_data_int;
66 for (auto it = header_map.begin(); it != header_map.end(); it++)
67 {
68 csv_data_int[it->second].resize(rows - 1, 0.0);
69 }
70
71 // Read columns associated to header tokens
72 std::string line;
73 int line_counter = 0;
74 int parsed_row_counter = first_value_row; // header already parsed.
75
76 while (std::getline(file_, line))
77 {
78 std::stringstream row_stream(line);
79 std::string token;
80 int column_counter = 0;
81
82 double item;
83 while (std::getline(row_stream, token, delim))
84 {
85 if (column_counter >= (int)header_map.size())
86 {
87 std::cout << "ReadCsv(): Warning: too many entries in row!" << std::endl;
88 ++column_counter; // to indicate a corrupted row
89 break;
90 }
91
92 std::istringstream is(token);
93 is >> item;
94 csv_data_int[header_map[column_counter]][line_counter] = (item);
95 ++column_counter;
96 }
97
98 // check if row was corrupted, if so, overwrite current line with the next one
99 if (column_counter != (int)header_map.size())
100 {
101 std::cout << "ReadCsv(): Warning: corrupted row=" << parsed_row_counter << " will be skipped!" << std::endl;
102 }
103 else
104 {
105 line_counter++;
106 }
107
108 // increment parsed row counter
109 parsed_row_counter++;
110 }
111
112 // shrink to the actual size
113 for (auto it = header_map.begin(); it != header_map.end(); it++)
114 {
115 csv_data_int[it->second].resize(line_counter);
116 }
117
118 file_.close();
119
120 *csv_data = csv_data_int;
121 }
122
123private:
124 std::ifstream file_;
125
126 HeaderMapType get_header(const int& row = 0)
127 {
129
130 HeaderMapType header_data;
131
132 int count = 0;
133 std::string line;
134 std::getline(file_, line);
135 std::stringstream row_stream(line);
136 std::string token;
137
138 while (std::getline(row_stream, token, delim))
139 {
140 token.erase(remove_if(token.begin(), token.end(), isspace), token.end());
141
142 header_data[count] = token;
143 count++;
144 }
145
146 file_.clear(); // reset line counter
147 file_.seekg(0, std::ios::beg);
148 return header_data;
149 }
150
152 {
153 int count = 0;
154 std::string line;
155 while (std::getline(file_, line))
156 {
157 if (std::isdigit(line[line.find_first_not_of(" \t")]))
158 {
159 break;
160 }
161
162 ++count;
163 }
164
165 file_.clear(); // reset line counter
166 file_.seekg(0, std::ios::beg);
167 return count;
168 }
169
170 void set_line_couter_of_file(const int& line_number)
171 {
172 file_.clear(); // reset line counter
173 file_.seekg(0, std::ios::beg);
174
175 std::string line;
176 for (int k = 0; k < line_number; k++)
177 {
178 std::getline(file_, line);
179 }
180 }
181
183 {
184 int count = 0;
185 std::string line;
186 while (std::getline(file_, line))
187 {
188 ++count;
189 }
190 file_.clear(); // reset line counter
191 file_.seekg(0, std::ios::beg);
192 return count;
193 }
194};
195} // namespace mars
196
197#endif // READ_CSV_H
Definition read_csv.h:30
HeaderMapType get_header(const int &row=0)
Definition read_csv.h:126
ReadCsv(CsvDataType *csv_data, const std::string &file_path, char delim_=',')
Definition read_csv.h:35
char delim
Definition read_csv.h:31
int check_for_header()
Definition read_csv.h:151
void set_line_couter_of_file(const int &line_number)
Definition read_csv.h:170
std::ifstream file_
Definition read_csv.h:124
int get_rows()
Definition read_csv.h:182
HeaderMapType header_map
Definition read_csv.h:32
static bool IsFile(const std::string &name)
filesystem::IsFile Check if the given path results in a file
Definition buffer.h:27
std::map< std::string, std::vector< double > > CsvDataType
Definition read_csv.h:26
std::map< int, std::string > HeaderMapType
Definition read_csv.h:27