Question

I am using visual studio 2012 writing normal c++ and I keep getting this error for a variable I have declared.

1>c:\users\joe\skydrive\documents\c++\consoleapplication2\matracies 1.cpp(182): error C2065: 'file' : undeclared identifier
1>c:\users\joe\skydrive\documents\c++\consoleapplication2\matracies 1.cpp(184): error C2065: 'file' : undeclared identifier

This is the function where I am getting the error.

void WriteMatrix(vector<vector<float>> Matrix, float row, float col, int choice)
{
if (choice == 1)
{
    ofstream file("MultiplyMatrix.txt", ios::app);
}
else if (choice == 2)
{
    ofstream file("AddMatrix.txt", ios::app);
}
else if (choice == 3)
{
    ofstream file("AddMatrix.txt", ios::app);
}
for(int i=0; i<row; i++)
{
    for(int j=0; j<col; j++)
    {
        float temp = Matrix[i][j];
        file<<temp<<" ";
    }
    file<<endl;
}
file<<endl;
file.close();
}
Was it helpful?

Solution 2

You are trying to access the file variable outside the conditional branches where its life is over. When you declare them within the { ... } conditional blocks, it will go out of scope at the closing bracket.

The proper solution would be either to declare it in the beginning of your function outside the scope of the conditional branches, and then open the desired files in the branches, or open only after the conditional block.

I would also consider using the switch statement in this case, rather than continous if/elseif/... as that is what the switch statement is for!

Therefore, your code would be like this (with proper indent, too):

void WriteMatrix(vector<vector<float>> Matrix, float row, float col, int choice)
{

This is the first alternative to be demonstrated and probably the nicest C++ solution:

    static const vector<string> filenameLookUpTable{"MultiplyMatrix.txt",
                                        "AddMatrix.txt", "AddMatrix.txt"};
    ofstream file(filenameLookUpTable.at(choice-1), ios::app);

You could also do:

    ofstream file;
    switch(choice) {
    case 1:
        file.open("MultiplyMatrix.txt", ios::app);
        break;
    case 2:
        file.open("AddMatrix.txt", ios::app);
        break;
    case 3:
        file.open("AddMatrix.txt", ios::app);
        break;
    }

You could also write this:

    string filename;
    switch(choice) {
    case 1:
        filename = "MultiplyMatrix.txt";
        break;
    case 2:
        filename = "AddMatrix.txt";
        break;
    case 3:
        filename = "AddMatrix.txt";
        break;
    }

    ofstream file(filename, ios::app);

and then the end, basically:

    for(int i=0; i<row; i++)
    {
        for(int j=0; j<col; j++)
        {
            float temp = Matrix[i][j];
            file<<temp<<" ";
        }
        file<<endl;
    }

    file<<endl;
    file.close();
}

OTHER TIPS

As Oli said, file only exists in the block within which it's defined.

You need to define file before the if statements. Then use file.open to open the chosen file.

And consider what happens if choice is neither 1, 2, or 3.

In C++ { } is used to denote scope. This means that file is only declared within your if statements. You can fix this by declaring file outside your if statements and opening them inside:

ofstream file; int choice;
if (choice == 1)
{
    file.open("MultiplyMatrix.txt", ios::app);
}
else if (choice == 2)
{
    file.open("AddMatrix.txt", ios::app);
}
else if (choice == 3)
{
    file.open("AddMatrix.txt", ios::app);
}
    return 0;
}
void WriteMatrix(vector<vector<float>> Matrix, float row, float col, int choice)

This passes Matrix by value, which means copying, which can be time consuming for a large matrix. Instead pass it by reference, to const if it's not supposed to be changed. Also, the floatargument type for row and col is unreasonable; make that int.

void WriteMatrix(vector<vector<float>> const& Matrix, int row, int col, int choice)

Then this code,

if (choice == 1)
{
    ofstream file("MultiplyMatrix.txt", ios::app);
}
else if (choice == 2)
{
    ofstream file("AddMatrix.txt", ios::app);
}
else if (choice == 3)
{
    ofstream file("AddMatrix.txt", ios::app);
}

does two things:

  • it chooses the filename,

  • it triplicates code for opening and closing a file.

In each branch the file variable is a local automatic variable which ceases to exist (hence, the file closing) at the end of that curly braces block.

The triple redundancy is ungood, and not having access to the variable where it's intended to be used, later on, is ungood. So move that logic to after the file name selection. Then, the selection itself can be reduced to simple array indexing:

assert( 1 <= choice && choice <= 3 );
static char const* const names =
{ "MultiplyMatrix.txt", "AddMatrix.txt", "AddMatrix.txt" };

ofstream file( names[choice - 1], ios::app);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top