Page MenuHomePhorge

No OneTemporary

Size
11 KB
Referenced Files
None
Subscribers
None
diff --git a/examples/CSVFiles/main.cpp b/examples/CSVFiles/main.cpp
index 68e287a..d457785 100644
--- a/examples/CSVFiles/main.cpp
+++ b/examples/CSVFiles/main.cpp
@@ -1,153 +1,157 @@
//===-- examples/CSVFiles/main.cpp --------------------------------*- C++ -*-===//
//
// The RoSA Framework -- Example CSVFiles
//
//===----------------------------------------------------------------------===//
///
/// \file examples/CSVFiles/main.cpp
///
/// \author Edwin Willegger (edwin.willegger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief This example shows how you could use the CSVIterator class to
/// get data into RoSA from a CSV-file.
//===----------------------------------------------------------------------===//
// To compile with dumping record layout:
// $ clang++ -o variadic-tuple -Xclang -fdump-record-layouts variadic-tuple.cpp
// -Wall -g -std=c++11
#include <cstdint>
#include <cstddef>
#include <iostream>
#include <istream>
#include <sstream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>
#include <typeinfo>
#include <map>
#include <algorithm>
#include <tuple>
#include <type_traits>
#include <unistd.h>
#include "rosa/support/csv/CSVReader.hpp"
#include "rosa/support/csv/CSVWriter.hpp"
const std::string AppName = "test-csvfiles";
//the example will be executed in the bin directory, but the data files are located in another the examples folder
const std::string Path = "../examples/CSVFiles/";
void testtupleCSVReader(){
//different streams to get the csv data out of the files
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_2("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_3("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_4("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_5("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_6("HR-New.csv");
//file contains no header an valid data entries, delimter = ','
std::ifstream file2("HR.csv");
//file contains header and valid data entries, delimter = ';'
std::ifstream file3("HR-New-Semicolon.csv");
rosa::csv::CSVIterator<int, std::string, std::string, int, int> it(file_header_data);
it.setDelimeter(',');
it++;
it++;
//if you iterate over the end of file, the last values
//of the file will remain in the data structure but no
//error occurs.
it++;
it++;
//-------------------------------------------------------------------
// a possiblity to get the data out of the iterator
std::tuple<int, std::string, std::string, int, int> value = *it;
std::cout << "Values are: " << std::get<0>(value) << " "
<< std::get<1>(value) << " ,are you now happy?" << std::endl;
//--------------------------------------------------------------------
//testing differnet parameters to the constructor
//uncomment to see that it is not possible to iterate over an vector in the tuple.
//rosa::csv::CSVIterator<double, std::vector<int>> it2(file, 1);
//try to skip a valid number of lines after the header
rosa::csv::CSVIterator<double, float, int, int, float> it2_0(file_header_data_2, 1);
//try to skip a valid number of lines after the header, but you assume that the file has no header
//uncomment this line to crash the programm
//rosa::csv::CSVIterator<double, float, int, int, float> it2_1(file_header_data_3, 0, rosa::csv::HeaderInformation::HasNoHeader);
//try to skip a valid number of lines after the header, but you assume that the file has no header
//uncomment this line to crash the program
// rosa::csv::CSVIterator<double, float, int, int, float> it2_2(file_header_data_4, 1, rosa::csv::HeaderInformation::HasNoHeader);
//try to skip a valid number of lines of a file without header
rosa::csv::CSVIterator<double, float, int, int, float> it2_3(file2, 1, rosa::csv::HeaderInformation::HasNoHeader);
//try to skip a valid number of lines after the header, but with different delimeter
rosa::csv::CSVIterator<double, float, int, int, float> it2_4(file3, 2,rosa::csv::HeaderInformation::HasHeader, ';');
// if you skip more lines than valid, you generate an infinte loop
//rosa::csv::CSVIterator<double, float, int, int, float> it3(file_header_data_5, 500);
//if you don't need data from all columns just select the number of columns you
//need. You get the data back from the first column (index 0) to the fourth column
//all values from the fifth column are ignored.
rosa::csv::CSVIterator<double, float, int, float> it4(file_header_data_6);
}
void testtupleCSVWriter(){
std::ofstream file_header_out("csvwriter_noheader.csv");
rosa::csv::CSVTupleWriter<int, float, std::string> wri(file_header_out);
std::tuple<int, float, std::string> values(5, 8.3, "hallo");
std::tuple<int, float, std::string> values2(3, 8.3, "end");
- std::vector<std::string> header;
- header.push_back("first column");
- header.push_back("second column");
- header.push_back("third column");
+ std::array<std::string, 3> header {"first column", "second column", "third column"};
+
+ //wrong header size, which is unable to write as a header to the tuples above.
+ std::array<std::string, 4> headerWrong {"first column", "second column", "third column", "fourth column"};
wri.writeHeader(header);
wri.write(values);
wri.write(values);
wri.write(values);
wri << values;
wri << values2;
+ //uncomment this line to see, that you can't write a header with the wrong number of elements.
+ //wri.writeHeader(headerWrong);
+
+
}
int main(void) {
std::cout << "This is a short example to show you how you could use the CSVIterator class." << std::endl;
std::cout << "There are also some limitations explained in the source code of the example." << std::endl;
std::cout << "Testing CSVWriter CSVTupleItrator implementation: " << std::endl;
testtupleCSVWriter();
std::cout << "Testing CSVReader CSVTupleIterator implementation: " << std::endl;
testtupleCSVReader();
std::cout << "All tests finished sucessfully" << std::endl;
return 0;
}
diff --git a/include/rosa/support/csv/CSVWriter.hpp b/include/rosa/support/csv/CSVWriter.hpp
index b7d5389..5eb21ee 100755
--- a/include/rosa/support/csv/CSVWriter.hpp
+++ b/include/rosa/support/csv/CSVWriter.hpp
@@ -1,177 +1,180 @@
//===-- rosa/support/csv/CSVWriter.hpp --------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/support/csv/CSVWriter.hpp
///
/// \authors David Juhasz (david.juhasz@tuwien.ac.at)
/// Edwin Willegger (edwin.willegger@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Facitilities to write CSV files.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_SUPPORT_CSV_CSVWRITER_HPP
#define ROSA_SUPPORT_CSV_CSVWRITER_HPP
#include <iostream>
#include <ostream>
#include <tuple>
#include <vector>
+#include <array>
namespace rosa {
namespace csv {
/// Provides facilities to write values into a CSV file.
///
/// The writer emits a comma, the character `,`, between each written values.
/// The resulted stream is a flat CSV file as it consists of onlyone row, no new
/// line is emitted.
///
/// \tparam T type of values to write
template <typename T>
class CSVWriter {
public:
/// Creates a new instance.
///
/// \param [in,out] S output stream to write to
///
/// \note The writer operates on non-binary outputs as long as \p S is in
/// good state.
CSVWriter(std::ostream &S)
: Str(S.good() && !(S.flags() & std::ios::binary) ? &S : nullptr),
IsFirst(true) {}
/// Tells if the last operation was successful.
///
/// \return if the last operation was successful
bool good(void) const noexcept {
return Str != nullptr;
}
/// Writes an entry to the output stream.
///
/// The implementation does anything only if the last operation was
/// successful. If so, \p V is written to \c rosa::csv::CSVWriter::Str.
/// The emitted value is preceded with a comma if the actual call is not the
/// first one for \p this object. Success of the operation is checked at the
/// end.
///
/// \param V value to write
void write(const T &V) {
if (Str) {
if (!IsFirst) {
*Str << ',';
} else {
IsFirst = false;
}
*Str << V;
if (!Str->good()) {
Str = nullptr;
}
}
}
private:
std::ostream *Str; ///< Output stream to write to.
bool IsFirst; ///< Denotes if the next write would be the first one.
};
/// Writes a tuple of values into a CSV file
///
/// \tparam Ts tpyes of values to write
template <typename... Ts> class CSVTupleWriter {
public:
/// Creates a new instance.
///
/// \param [in,out] S output stream to write to
///
/// \note The writer operates on non-binary outputs as long as \p S is in
/// good state.
CSVTupleWriter(std::ostream &S)
: Str(S.good() && !(S.flags() & std::ios::binary) ? &S : nullptr),
IsFirst(true) {}
/// Tells if the last operation was successful.
///
/// \return if the last operation was successful
bool good(void) const noexcept {
return Str != nullptr;
}
template<size_t i = 0>
void write(std::tuple<Ts...> values) {
size_t size = 0;
std::cout << "Writing tuple values into file" << std::endl;
std::cout << "Tuple has ";
std::cout << std::tuple_size<decltype (values)>::value;
std::cout << " elements." << std::endl;
size = std::tuple_size<decltype (values)>::value;
std::cout << std::get<i>(values) << std::endl;
if(Str){
if constexpr(i+1 != sizeof...(Ts)){
*Str << std::get<i>(values) << ", ";
write<i+1>(values);
}else if constexpr(i + 1 == sizeof...(Ts)){
*Str << std::get<i>(values) << '\n';
}
}
}
- void writeHeader(std::vector<std::string> header){
+ void writeHeader(std::array<std::string, sizeof...(Ts)> header){
size_t index = 0;
if(Str){
index = 0;
for (auto i = header.begin(); i != header.end(); ++i){
index = index + 1;
if(index != header.size()){
*Str << *i << ", ";
}else {
*Str << *i;
}
}
*Str << '\n';
}
}
private:
std::ostream *Str; ///< Output stream to write to.
bool IsFirst; ///< Denotes if the next write would be the first one.
+ const size_t tupleSize = sizeof...(Ts); /// explicitly the number of elements of the tuple.
+
};
template <typename... Ts>
CSVTupleWriter<Ts...> &operator<<(CSVTupleWriter<Ts...> &W, const std::tuple<Ts...> V)
{
W.write(V);
return W;
}
/// Writes a value to a CSV file with \c rosa::csv::CSVWriter.
///
/// \see rosa::csv::CSVWriter
///
/// \tparam T type of value to write
///
/// \param [in,out] W object to write with
/// \param V value to write
///
/// \return \p W after writing \p V with it
template <typename T>
CSVWriter<T> &operator<<(CSVWriter<T> &W, const T& V) {
W.write(V);
return W;
}
} // End namespace csv
} // End namespace rosa
#endif // ROSA_SUPPORT_CSV_CSVWRITER_HPP

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 1:11 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157169
Default Alt Text
(11 KB)

Event Timeline