There are many, many errors in your program. Let me list up the most important:
- Usage of raw pointers for owned memory. Never do this in C++ (if at all, use
std::unique_ptr instead)
- Do not use
new in C++ to allocate memory (use std::make_unique)
- If you allocate memory with
new, then you must delete it afterwards
- Best: Do use container from the standard library, in this case
std::vector
- Always initialize all variables
- Always check the result of file operations like open or >>
- Handle errors
- Use
++v instead of v++
- Define variables, when you need them. Keep them scoped. Prevent Namespace pollution
- If you want to write C++ code, then use C++ language elements and not C
- Try to design your code with modern C++ language elements
So. I fixed your code, so that it runs, reads your example file and displays the result. I removed the major bugs. Please see:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
float*** get3dArry(unsigned short widthX, unsigned short widthY, unsigned short widthZ) {
unsigned short int i, j, x, y, z;
float clvDefault = 0.0;
float*** Cl = new float** [widthZ];
for (i = 0; i < widthZ; i++)
{
Cl[i] = new float* [widthY];
for (j = 0; j < widthY; j++)
{
Cl[i][j] = new float[widthX];
}
}
std::ifstream clvIn;
std::string clvFileName = "r:\\File_read.csv";
clvIn.open(clvFileName.c_str());
if (clvIn.fail())
{
std::cerr << "\n*** Error: Could not open input file\n";
}
else {
std::string filejunk, line;
char delim;
//std::getline(clvIn, filejunk);
int clvX, clvY, clvZ;
float clvValue;
for (z = 0; z < widthZ; z++)
{
for (y = 0; y < widthY; y++)
{
for (x = 0; x < widthX; x++)
{
Cl[z][y][x] = clvDefault;
}
}
}
for (y = 0; (y < widthY) && std::getline(clvIn, line); ++y) {
std::istringstream iss{ line };
for (x = 0; (x < widthY) && (iss >> Cl[0][y][x]); ++x)
;
}
for (z = 0; z < widthZ; z++)
{
for (y = 0; y < widthY; y++)
{
for (x = 0; x < widthX; x++)
{
Cl[z][y][x] = Cl[0][y][x];
}
}
}
}
return Cl;
}
int main() {
float*** a3d = get3dArry(4, 4, 3);
for (int z = 0; z < 3; ++z) {
std::cout << "\n";
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
std::cout << a3d[z][y][x] << "\t";
}
std::cout << "\n";
delete[] a3d[z][y];
}
delete[] a3d[z];
}
delete[] a3d;
return 0;
}
However. I would not recommend to use that. The quality is too bad. It is error prone and somehow still complete a C-Program.
Please see the part, where I read the CSV file. Of course, there is no external library necessary. I hear often such nonesense recomendations for ultra simple CSV files. So, no library. Example from above code:
for (y = 0; (y < widthY) && std::getline(clvIn, line); ++y) {
std::istringstream iss{ line };
for (x = 0; (x < widthY) && (iss >> Cl[0][y][x]); ++x)
;
}
Nobody can persuade me, that I need a library, for what I can do with 3 simple lines of code.
If you are interested to learn, then I show you also a "more-modern" C++ solution:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
// Make reading datatypes easier
using DataType = float;
using Matrix1dX = std::vector<DataType>;
using Matrix2dYX = std::vector<Matrix1dX>;
using Matrix3dZYX = std::vector<Matrix2dYX>;
// This is the number of z values for the 3rd dimension. Whatever you want
constexpr size_t NumberOfDimensionZ = 3U;
int main() {
// Open input csv file, and check, if open operation worked
if (std::ifstream clvIn("r:\\File_read.csv"); clvIn) {
// Define 2d array and initialize all values with 0.0;
Matrix2dYX myx{};
// Read all lines of the file and split values
for (std::string line{}; std::getline(clvIn, line); ) {
// Convert just read string to a std::istringstream
std::istringstream iss{ line };
// Add the new values to the 2d array. Iterate over all values in one line
// then create a 1d vector inplace and add this line values to our 2d matrix
myx.emplace_back(Matrix1dX(std::istream_iterator<DataType>(iss), {}));
}
// Define a 3d matrix, with a given size and having each z-value be the data from the csv file
Matrix3dZYX mzyx(NumberOfDimensionZ, myx);
// Some debug output
// Show result to user
for (const Matrix2dYX& m2 : mzyx) {
std::cout << "\n";
for (const Matrix1dX& m1 : m2) {
for (const DataType& d : m1) std::cout << d << "\t";
std::cout << "\n";
}
}
}
else {
std::cerr << "\n*** Error: Could not open input file\n";
}
return 0;
}
Please note that you can write elegant very elegant and compact code in C++.
For reading the file and creating the 3d vector, I do not need any loop.
Please read and try to understand. Please google unknwon language constructs. If you do not understand, then ask.
returnor similar in your file error handling code, otherwise the code keeps executing as if the file open was successful.widthZpointers towidthYpointers towidthXfloat. Is that what you intend? Your code is set up that way and it doesn't matter what letters you use, but that is a bit in reverse of what you normally see.