Hi Everyone,

I have a program that takes data in a two dimensional array, performs simple calculations, and then writes the data to a file. When I call the function that calculates and writes, I get an error on the two dimensional array stating: "argument of type 'int' is incompatible with parameter of type 'int(*)[5]'." .I am not sure why this suddenly changed to italics....ok but I am not sure why this error is happening.

//Call writing function
storeProportions(output, dropsOf[3][4], totals, numFailed);  //located in main

//Function prototype
void storeProportions(ofstream output, int values[][NUM_COMPONENTS], int totals, int numRows);

//2d array in main
int dropsOf[numFailed][NUM_COMPONENTS] = {{3, 6, 2, 0, 5},
                                                {4, 0, 0, 5, 3},
                                                {0, 0, 0, 0, 0},
                                                {2, 1, 0, 0, 2}};

The second parameter is incorrect -- do not specify the dimensions

storeProportions(output, dropsOf, totals, numFailed); //located in main

Ahh ok. that did it. so now the problem I am having is with my output file. I am not sure why, but it is blank. Here is the function that writes:

void storeProportions(ofstream output, int values[][NUM_COMPONENTS], int totals, int numRows)
{
    double finalOutput = 0;

    for(int count = 0; count <= (numRows * NUM_COMPONENTS); count++)
    {
        finalOutput = values[count][NUM_COMPONENTS] / totals);
        output << finalOutput << endl;
    }
return; 
}

ofstream must be passed by reference, not by value as you have done. Not: don't use a calculated value in the loop condition because it is calculated on every loop iteration. Make the calcuation before the loop starts then use it in the loop condition, as shown below.

void storeProportions(ofstream& output, int values[][NUM_COMPONENTS], int totals, int numRows)
{
    double finalOutput = 0;
    int maxnum = numRows * NUM_COMPONENTS);
    for(int count = 0; count <= maxnum; count++)
    {
        output << values[count][NUM_COMPONENTS] / totals) << endl;
    }
}

The above code still is incorrect because there is no such element as values[cound][NUM_COMPONENTS]. Are you attempting to write all the array values to a file? If yes then you will need two loops

    void storeProportions(ofstream& output, int values[][NUM_COMPONENTS], int totals, int numRows)
    {
        double finalOutput = 0;
        for(int count = 0; count < numRows; count++)
        {
            for(int j = 0; j < NUM_COMPONENTS; j++)
            output << values[count][j] / totals) << "\t";
        }
        output << "\n"; // new line
    }

Edited 3 Years Ago by Ancient Dragon

Oh good catch. Thank you
*Edit. Oh yes, I am writing to a file, and some answers are very wrong, so I was about to start working on it. Thanks for the extra info!

Edited 3 Years Ago by breezett93

why are two loops necessary?

Also, the small calculation I need to do before writing, is take (drops of substance x) / (total drops). In this case, (total drops) = 34

Edited 3 Years Ago by breezett93

It would be helpful to name the variables something meaningful, especially if you want to post the code on a forum such as this one. No one has a clue what values[][], totals, NUM_COMPONENTS, etc are supposed to represent. Whether two loops are necessary depends on what you want to write to the file. Certainly values[x][NUM_COMPONENTS] is incorrect because NUM_COMPONENTS probably exceeds the array bounds. I said "probably" because I don't know how you declared values variable. So without more information it's almost impossible for anyone to determine what should be written to the file.

As for the calculations, notice that the value of numRows never changes within the loop, so why calculate numRows * NUM_COMPONENTS on every loop iteration? Make the calculation only once before the loop and use that in the loop.

@AD Wont the compiler see that the value of the expression never changes and optimize it away?

Edited 3 Years Ago by NathanOliver

Ok, apologies on being vague. These are all the variables used in main.

//Declare variables
    string filename;
    ofstream output;    
    const int numFailed = 4;    //number of failed tests which happens to equal the number of rows
    int totals = 0;
    int totalDrops[] = {17, 12, 0, 5};   //total tests by row
    int dropsOf[numFailed][NUM_COMPONENTS] = {{3, 6, 2, 0, 5},   //all of the tests
                                            {4, 0, 0, 5, 3},
                                            {0, 0, 0, 0, 0},
                                            {2, 1, 0, 0, 2}};

So NUM_COMPONENTS is the number of elements per row. You are correct, numRows remains constant. Each element represesnts the number of times a certain situation was tested. So then 'totals' is the total number of tests overall which is also a constant value.

So in my output file, I would like the data to look just like dropsOf[][] with 4 rows and 5 columns so its easy to compare the final results to the original. However, right now, every single output value is 0. So something must be amiss in my calculating. Because you mentioned I need two loops to write data to a file, I adapted your code.

void storeProportions(ofstream& output, int values[][NUM_COMPONENTS], int totals, int numRows)
{
    double finalOutput = 0;
    for(int count = 0; count <= numRows; count++)
    {
        for(int count2 = 0; count2 <= NUM_COMPONENTS; count2++)
        output << values[count][count2] / totals << "\t";
    }
    output << "\n"; 
    return;
}

So in my output file, I would like the data to look just like dropsOf[][] with 4 rows and 5 columns

Yes, you need two loops for that, one for the rows and the other for the column s

for(int count = 0; count <= numRows; count++)

Wrong. count goes up to, but not including, NumRows. Count them on your fingures if you have to -- 0, 1, 2, 3 and 4. That makes 5 columns. There is no such column number as NUM_COMPONENTS (which is 5 in your program). You have the same problem with the inner loop.

Edited 3 Years Ago by Ancient Dragon

Your issue is with integer conversion. Lets say, for example that you send the array that you showed, and say 4 for totals. At values[0][0] the result is 3 right? So you can pretend to swap in a 3 there... and swap in 4 for totals. What does 3/4 become in c++ (NOTE: integer division!). The answer is 0. That is why its all writing 0s. If you want the original array then don't divide by totals, if you want the fractional value then try (double)values[count][count2]/totals so as to call floating point arithmetic.

@AD I have NUM_COMPONENTS declared as a const int above main.
@Lab Thank you.

Decimal values are starting to show up, but in the first row, the values are half of what they are supposed to be. In the subsequent rows, the answers get more inaccurate.

Also, I would like the data to be displayed with 4 rows and 5 columns, just like dropsOf[][]. I do know I need #include<iomanip> and 'fixed', but what else do I need?

Edited 3 Years Ago by breezett93

The loops have already been posted two or three times in this thread. You yourself posted the loops just a couple hours ago. You don't have to include anything else -- just get the loops correct.

One thing you can do is swap the order of your counts. Giving them descriptive names could help. For example:

int myArray[height][width]={0};//or whatever
for (int x=0; x<width; ++x) //loop through x SECOND! (since this is the outside loop)
{
    for (int y=0; y<height; ++y) //loop through y FIRST! (check it by hand if you don't believe me)
        doSomethingWith(myArray[y][x]);
    //do things that happen once per x here 
}
//If you want to loop by x first, then y:
for (int y=0; y<height; ++y)
{
    for (int x=0; x<width; ++x)
        doSomethingWith(myArray[y][x]);
    //again... do things that happen once per y here
}

As such your problem I think would be the ordering of your loops. Also I never use iomanip, iostream has everything you need for this. Google for the manip functions of cout... I don't know them off-hand. (or maybe somebody will lend their memory here instead).

This article has been dead for over six months. Start a new discussion instead.