Skip to content
Snippets Groups Projects
CSVReader.cpp 3.38 KiB
Newer Older
  • Learn to ignore specific revisions
  • //
    // Created by martin on 14.11.18.
    //
    
    
    #include <string>
    #include <fstream>
    #include <sstream>
    
    #include "CSVReader.h"
    
    #include "../exceptions.h"
    
    
    namespace lib4neuro {
        CSVReader::CSVReader(std::string file_path, std::string delimiter, bool ignore_first_line) {
    
            if(!std::filesystem::exists(file_path)) {
    
                THROW_RUNTIME_ERROR("The specified file path in CSVReader does not exist!");
    
            this->file_path = file_path;
            this->delimiter = delimiter;
            this->ignore_first_line = ignore_first_line;
            this->header_included = ignore_first_line;
            this->data = new std::vector<std::vector<std::string>>;
        }
    
        void CSVReader::read() {
            std::ifstream ifs(this->file_path);
            std::string line;
    
            if(this->ignore_first_line) {
                std::getline(ifs, line);
            }
    
            /* Read single line from the file */
            while(std::getline(ifs, line)) {
    
                /* Ignore empty line */
                if(line == "") {
                    continue;
                }
    
                /* Separate elements of the line according to the delimiter */
                size_t last = 0;
                size_t next = 0;
                std::vector<std::string> separated_line;
                while ((next = line.find(this->delimiter, last)) != std::string::npos) {
                    separated_line.emplace_back(line.substr(last, next - last));
                    last = next + 1;
                }
                separated_line.emplace_back(line.substr(last));
    
                /* Store the elements from the line to the vector with data */
                this->data->emplace_back(separated_line);
            }
    
            ifs.close();
        }
    
        std::vector<std::vector<std::string>>* CSVReader::get_data() {
            return this->data;
        }
    
        void CSVReader::print_data() {
            for(auto line : *this->data) {
                for(auto e : line) {
                    std::cout << e << " ";
                }
                std::cout << std::endl;
            }
        }
    
        DataSet CSVReader::get_data_set(std::vector<unsigned int>* input_col_indices,
                                        std::vector<unsigned int>* output_col_indices) {
    
            std::vector<std::pair<std::vector<double>, std::vector<double>>> data_set_contents;
    
            for(auto line : *this->data) {
    
                //TODO check empty values in data
    
                std::vector<double> input;
                for(auto ind : *input_col_indices) {
    
                    try {
                        /* Check, if the string is a number */
                        if(!std::regex_match( line.at(ind), std::regex( ( "((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?" ) ))) {
                            THROW_RUNTIME_ERROR(std::string("Value \"") + line.at(ind) + "\" is not numerical and so it cannot be used in Data Set!");
                        }
    
                        /* Add loaded number to the vector of inputs */
                        input.push_back(std::stod(line.at(ind)));
    
                    } catch(const std::out_of_range& e) {
                        THROW_OUT_OF_RANGE_ERROR("Non-existing index specified (" + std::to_string(ind) + ")!");
                    }
    
                }
    
                std::vector<double> output;
                for(auto ind : *output_col_indices) {
                    output.emplace_back(std::stod(line.at(ind)));
                }
    
    
                data_set_contents.emplace_back(std::make_pair(input, output));
    
            return DataSet(&data_set_contents);