Home > Software design >  Reading file in 2d array
Reading file in 2d array

Time:12-22

I am trying in this function to read data from csv file in 2d array but when print the array the output is zero, What is the issue? The file has 5 rows and 500 columns

void readFilesToReadings() {
int row = 5;
int col = 10;

int myArray[row][col];
string fileName, BasefileName = "C:/Users/hhh/Desktop/frac/Z500.csv"
//Opening the file
ifstream inputfile(fileName);

if (!inputfile.is_open()) 
cout<<"Error opening file" ;

//Defining the loop for getting input from the file

for (int r = 0; r < row; r  ) //Outer loop for rows
{
    for (int c = 0; c < col; c  ) //inner loop for columns
    {
      inputfile >> myArray[r][c];  //Take input from file and put into myArray
    }
}

for (int r = 0; r < row; r  )
{
    for (int c = 0; c < col; c  )
    {
        cout << myArray[r][c] << "\t";
    }
    cout<<endl;
}

}

CodePudding user response:

Here's the fixed code, you were only setting BasefileName (which was never used, and fileName was not set, so of course your file open failed. (I've tested with my own csv and they now works):

void readFilesToReadings() {
   const int row = 5;
   const int col = 10;

   int myArray[row][col];
   string fileName = "C:/Users/hhh/Desktop/frac/Z500.csv";
   
   //Opening the file
   ifstream inputfile(fileName);

   if (!inputfile.is_open())
   {
      cout << "Error opening file";
   }
   else {

      //Defining the loop for getting input from the file

      for (int r = 0; r < row; r  ) //Outer loop for rows
      {
          for (int c = 0; c < col; c  ) //inner loop for columns
          {
             inputfile >> myArray[r][c];  //Take input from file and put into myArray
          }
      }

      for (int r = 0; r < row; r  )
      {
          for (int c = 0; c < col; c  )
          {
              cout << myArray[r][c] << "\t";
          }
          cout << endl;
      }
   }

}

CodePudding user response:

Reading stuff from file is not difficult in C , but there is a pattern you should follow. It is easiest to make yourself a little function to implement this pattern.

#include <fstream>
#include <iostream>
#include <string>

template <typename T, size_t ROWS, size_t COLUMNS>
bool load_readings_from_file( 
    const std::string & filename, 
    T (&array)[ROWS][COLUMNS], 
    char delimiter = ',' )
{
    std::ifstream f( filename );
    for (size_t row = 0;  row < ROWS;  row  )
    {
        for (size_t column = 0;  column < COLUMNS;  column  )
        {
            f >> std::ws;
            if (f.peek() == delimiter) f.get();
            f >> array[row][column];
        }
    }
    return (bool)f;
}

I have used templates so you can pass any size array you want to it, but you could easily hardcode the array type (size) in the global namespace if you want.

using ReadingsArrayType = int[5][10];

bool load_readings_from_file(
    const std::string & filename,
    ReadingsArrayType array,
    char delimiter = ',' )
{
    ...
}

Either way, using it to fill an array from file is about as easy as it looks:

int main()
{
    constexpr int rows = 5;
    constexpr int cols = 10;
    
    int myReadingsArray[rows][cols];
    
    if (!load_readings_from_file( "C:/Users/hhh/Desktop/frac/Z500.csv", myReadingsArray ))
    {
        std::cerr << "Could not load file!\n";
        return 1;
    }
    
    // Print the matrix
    for (int r = 0;  r < rows;  r  )
    {
        for (int c = 0;  c < cols;  c  )
        {
            std::cout << myReadingsArray[r][c] << "\t";
        }
        std::cout << "\n";
    }
}

(Again, if you use the array type directly:

int main()
{
    ReadingsArrayType myReadingsArray;

    if (!load_readings_from_file( ... )) ...

As you can see it is much less clear that myReadingsArray is, in fact, an array... So I personally tend to avoid this kind of type aliasing.)

Finally, you should generally avoid using absolute paths for your filenames. Put the data in the same directory as your executable, or a subdirectory of it. Better yet, let the user supply a filename:

int main( int argc, char ** argv )
{
    if (argc != 2)
    {
        std::cerr << "usage:\n  myprog FILENAME\n";
        return 1;
    }

    const char * filename = argv[1];

    int myReadingsArray[5][10];

    if (!load_readings_from_file( filename, myReadingsArray )) ...

Creating functions to do stuff is just one step away from applying the full power of C to serialize objects for you. You’ll get to that a little later.

  • Related