Read table of numbers into arrays when number of rows and columns determined at runtime

廉价感情. 提交于 2019-12-04 18:12:53

Note doing this:

while (!infile.eof()){

Is nearly always wrong. If the file reading fails for any other reason than eof then you enter an infinite loop.

Also the way you code is organized this will also mean that you try and initialize your data twice (though it will fail on the second pass an not do anything (apart from re-do the loop)) as the eof flag is not set until you read past the EOF and since you know how much data to read your first pass will not read past the EOF, you will read all the way up-to (but not past).

Reading into a 1D array

int main()
{
    std::ifstream file("plop");

    int n;
    int m;
    std::string ColHeadX;
    std::string ColHeadY;
    // You forgot to read the Col Header out.
    // Just read them into strings.
    file >> n >> m >> ColHeadX >> ColHeadY;

    // Don't do manual memory management.
    // Use a vector it will do the work for you.
    std::vector<double>   data(n*m); // initialized with (n*m) elemensts

    // Always put the read in the loop test
    //      This bit:  file >> data[loop]
    // If this read fails you want the loop to exit immediately.
    // By putting the read here the result of the read will be
    // tested to see if it worked.
    for(int loop=0;loop < (n*m) && (file >> data[loop]); ++loop) { /*Empty*/}
}

Reading into a 2D array is nearly as simple:

int main()
{
    std::ifstream file("plop");

    int n;
    int m;
    std::string ColHeadX;
    std::string ColHeadY;
    // You forgot to read the Col Header out.
    // Just read them into strings.
    file >> n >> m >> ColHeadX >> ColHeadY;

    // Don't do manual memory management.
    // A vector of vectors gives you a 2D array.
    // The initialize(r) is slightly more complex but given the example above
    // I think you should be able to see the outer vector is initialized with
    // n copies of a vector with m elements. 
    std::vector<std::vector<double> >   data(n,std::vector<double>(m));


    // Again I would advise putting the read in the loop condition
    // The easiest way here is then to calculate the x/y coordinates in the body as you go.
    for(int loop=0, x=0, y=0;loop < (n*m) && (file >> data[x][y]);)
    {
       ++loop
       x = loop % n;
       y = loop / n;
    }

}

To allocate the two-dimensional array inside your function, use:

float **mat = new float*[m];

for(int i=0; i<m; i++){
    mat[i] = new float[n];
}

Then you can change infile >> mat[i*n+j]; to:

infile >> mat[i][j];

Finally, make sure you implement reading the title; right now it's empty:

//Read title

In C and C++, pointers (C and C++) and references (C++ only) to arrays are declared with a somewhat obscure syntax, like this:

void fp(float (*array)[10]);
void fr(float (&array)[10]);
void f2d(float (&array)[10][10]);


void main()
{
    float a[10];
    fp(&a);
    fr(a);

    float b[10][10];
    f2d(b);
}

You cannot declare a pointer or reference to an array that is not of compile-time constant size. To pass variable-sized data you need to use a pointer to the first element in the array and pass in the size of the data, so your code can safely use the array with out running out of bounds, like this:

void f(float* data, int length);

However, this places a burden on the programmer to carefully write safe and correct code. Since you're using C++ and not C, using std::vector is highly recommended! vector is a sequential container object that behaves just like an array when you need to index into it. It is dynamically resizable, and will handle the details of allocation and deallocation for you.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!