-4

I am trying to read hex values into a 2D array from a CSV file using c++. I am relatively new, so I could use some help.

I want to skip the first 98 lines (which consist mostly of text) and then read in the next 100 lines from the file. There are 22 comma separated columns and I only really need columns 8, 10, and 13-20. Column 8 contains a string and the rest contain hex values.

Below is what I have. It compiles (somehow) but I keep getting a segmentation fault. I think I need to dynamically allocate space for the array. Also, the code doesn't account for the string or int to hex conversion.

The main isn't doing anything currently, this is just from a test suite.

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <stdlib.h>

const int ROWS = 100; // CAN messages
const int COLS = 22; // Colums per message
const int BUFFSIZE = 80;

using namespace std;

int **readCSV() {

    int **array = 0;
    std::ifstream file( "power_steering.csv" );
    std::string line; 
    int col = 0;
    int row = 0;

    if (!file.is_open())
    {
        return 0;
    }

    for (int i = 1; i < 98; i++){
        std::getline(file, line); // skip the first 98 lines
    }

    while( std::getline( file, line ) ) {

        std::istringstream iss( line );
        std::string result;

        while( std::getline( iss, result, ',' ) ) {

            array[row][col] = atoi( result.c_str() );
            col = col+1;
        }
        row = row+1;
        col = 0;
    }
    return array;
}

int main() {

    int **array;
    array = readCSV();

    for (int i = 0; i < 100; i++) {
        cout<<array[i][0];
    }

    return 0;
}
Kal
  • 17
  • 5
  • 1
    The double pointer is an attempt to use c-style arrays. It makes the array[x][y] syntax work, but ONLY if you actually allocate memory for the pointer to point to. I suggest that you forget c-style arrays (they are hard to use safely) and read all about std::vector and/or std::array. You will be much happier.\ – Dale Wilson Aug 23 '16 at 21:31

1 Answers1

2

You are getting segmentation fault error since you are trying to store values in array[row][col] without allocating memory for array.

My suggestion: Don't use int** array;. Use std::vector<std::vector<int>> array; instead. That obviates the need to allocate and deallocate memory for the objects in your code. Let std::vector take care of memory management for you.

std::vector<std::vector<int>> readCSV() {

   std::vector<std::vector<int>> array;
   std::ifstream file( "power_steering.csv" );
   std::string line; 

   if (!file.is_open())
   {
      return array;
   }

   for (int i = 1; i < 98; i++){
      std::getline(file, line); // skip the first 98 lines
   }

   while( std::getline( file, line ) ) {

      std::istringstream iss( line );
      std::string result;

      std::vector<int> a2;
      while( std::getline( iss, result, ',' ) ) {
         a2.push_back(atoi( result.c_str() ));
      }

      array.push_back(a2);
   }

   return array;
}

int main() {

   std::vector<std::vector<int>> array = readCSV();

   for (int i = 0; i < 100; i++) {
      cout<<array[i][0];
   }

   return 0;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • This worked, thanks! But some of the columns contain 1 byte hex values stored as plain text (i.e FF or A7). If I read these in as ints then any letter value is dropped in the vector. Do you know a way to account for this? – Kal Aug 24 '16 at 17:09
  • @Kal, you need to convert the strings to `int` using a different technique. See [this post](http://stackoverflow.com/questions/1070497/c-convert-hex-string-to-signed-integer). – R Sahu Aug 24 '16 at 17:16
  • I was able to store the hex value as it's integer equivalent by replacing atoi( result.c_str() ) with strtoul( result.c_str(), NULL, 16 ) – Kal Aug 24 '16 at 19:07
  • @Kal, looks like you are all set. – R Sahu Aug 24 '16 at 19:08