'How can I import .csv file data into gsl_vectors in C++?

I have a .csv file that looks like:

X,Y,Z
0,0,0
0,0,0
-0.00624347,-0.0182673,1.00063
-0.00845628,-0.0374925,1.00058
-0.00494793,-0.0295639,0.927447
-0.00285682,-0.0926582,0.885783
-0.00832563,-0.02957,0.697834

And I want to put it into three gsl_vectors (from GSL: https://www.gnu.org/software/gsl/doc/html/vectors.html) corresponding to the column X, column Y and column Z respectively. The reason why I want to do this is because I later want to use the functions that are implemented in the GNU Scientific Library on this data. I want to emphasize that these functions can only work on gsl_vectors and not on std:vectors.

My approaches:

  1. Put the data from the .csv into std:vectors, and then transform those vectors into gsl_vectors. That did not work.

  2. Put the data from the .csv file into gsl_vectors directly:

    #include <iostream>
    #include <fstream>
    #include <istream>
    #include <string>
    #include <sstream>
    #include <algorithm>
    #include <gsl/gsl_linalg.h>
    #include <gsl/gsl_vector.h>
    
    struct acceleration {
        gsl_vector AccX;
        gsl_vector AccY;
        gsl_vector AccZ;
    };
    
    // Function prototypes
    acceleration read_csv(acceleration& A);
    // End function prototypes
    
    int main(void)
    {
        // ==================READ THE CSV=========================
        acceleration data;
        data = read_csv(data);
        printf("/n");
        gsl_vector_fprintf(stdout, &data.AccX, "%lf");
    
        return 0;
    }
    
    acceleration read_csv(acceleration& SA)
    {
        std::string buffer; /* Declare a buffer for the data that will be read */
        std::string bacx, bacy, bacz;
        std::ifstream inputfile;
        inputfile.open("buffer.csv"); /* Open file for reading */
        if (!inputfile.is_open())
        {
            std::cout << "Error opening file" << std::endl;
        }
    
        std::stringstream aux(buffer);
        getline(aux, bacx, ',');
        getline(aux, bacy, ',');
        getline(aux, bacz, ',');
        size_t i{ 0 };
    
        while (getline(inputfile, buffer))
        {
            std::stringstream aux(buffer);
    
            getline(aux, bacx, ',');
            if (bacx.compare("AX") != 0)
                gsl_vector_set(&SA.AccX, i, stod(bacx));
    
            getline(aux, bacy, ',');
            if (bacy.compare("AY") != 0)
                gsl_vector_set(&SA.AccY, i, stod(bacy));
    
            getline(aux, bacz, ',');
            if (bacz.compare("AZ") != 0)
                gsl_vector_set(&SA.AccZ, i, stod(bacz));
            i++;
        }
        inputfile.close();
        return (SA);
    
    }
    

    This gives no output on the Console and if I debug it, the function gsl_vector_set throws an exception:

    Exception thrown at 0x7A5EED1A (gsld.dll) in progr.exe: 0xC0000005: Access violation writing location 0x3333332

    At gsl_set_vector's line: v->data[i * v->stride] = x;

  3. Put the .csv data into a gsl_block and then slice it into gsl_vectors. Here I get an exception when trying to put the data into the block. Then, for slicing the block into vectors, I assume I'll have to use the gsl_vector_alloc_from_block() function, yet I did not find any example on how to use this function. I do need to see how others use functions generally because I'm new to C++. Here is what I have until now for this idea:

    #include <iostream>
    #include <fstream>
    #include <gsl/gsl_linalg.h>
    #include <gsl/gsl_vector.h>
    
    // Function prototypes
    gsl_block read_csv(void);
    // End function prototypes
    
    int main(void)
    {
        // ================== READ THE CSV INTO A BLOCK =========================
        gsl_block data;
        data = read_csv();
        // ================= NOW SLICE THE BLOCK: HOW? ==========================
        // Use gsl_vector_alloc_from_block(), but how?
        return 0;
    }
    
    // Function declarations
    gsl_block read_csv(void)
    {
        FILE* inputfile;
        fopen_s(&inputfile, "buffer.csv", "r"); /* Open file for reading */
        if (inputfile == NULL)
            std::cout << "file does not exist \n";
        fseek(inputfile, 0L, SEEK_END); // Go until the end
        int file_size = ftell(inputfile); // In order to tell the size of the file
        gsl_block* b = gsl_block_alloc(file_size);
        if(inputfile)
            gsl_block_fscanf(inputfile, b);
    
        fclose(inputfile);
    
        return *b;
    
    }
    // End function declarations
    

    If I run this I get:

    Debug Error! abort() has been called

    And on the Console it is shown:

    gsl: C:\DEV\vcpkg\buildtrees\gsl\src\gsl-2-fb511965d5.clean\block\fprintf_source.c:90: ERROR: fscanf failed Default GSL error handler invoked.

    If I debug this, the gsl_error function throws an exception:

    progr.exe has triggered a breakpoint.

    At abort ();

To sum up, I actually want to read the .csv file into gsl_vectors. If my approaches are not OK, it is understandable.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source