Search code examples
c++ofstream

Dynamically choose between output file to write


I have a Matrix class and a std::vector<Matrix>. I also have 3 stages of calculation and each stage produces a std::vector<Matrix> and I have to write these vectors of Matrix to stage1.txt,stage2.txt and stage3.txt. I have written a function for this which will take stage number as a parameter and output the vectors of Matrix to corresponding files. Currently my code looks like this:

void writeTrianglePointsToFile(int stage){
            std::vector <Matrix> stageTriangles;

            if(stage == 1) stageTriangles = stage1Triangles;
            else if(stage == 2) stageTriangles = stage2Triangles;
            else if(stage == 3) stageTriangles = stage3Triangles;

            for(int i = 0 ; i < stageTriangles.size() ; i++){
                int rows = stageTriangles[i].getMatrixRows() - 1; // discard last row
                int columns = stageTriangles[i].getMatrixColumns();
                for(int j = 0 ; j < columns ; j++){
                    for(int k = 0 ; k < rows ; k++){
                        if(stage == 1){
                            stage1OutputFile << std::fixed << std::setprecision(7) << std::showpoint << stageTriangles[i].matrix[k][j];
                            if(k != rows - 1) stage1OutputFile << " ";
                        } else if(stage == 2){
                            stage2OutputFile << std::fixed << std::setprecision(7) << std::showpoint << stageTriangles[i].matrix[k][j];
                            if(k != rows - 1) stage2OutputFile << " ";
                        } else if(stage == 3){
                            stage3OutputFile << std::fixed << std::setprecision(7) << std::showpoint << stageTriangles[i].matrix[k][j];
                            if(k != rows - 1) stage3OutputFile << " ";
                        }
                    }
                    if(stage == 1) stage1OutputFile << "\n";
                    else if(stage == 2) stage2OutputFile << "\n";
                    else if(stage == 3) stage3OutputFile << "\n";
                }
                if(stage == 1) stage1OutputFile << "\n";
                else if(stage == 2) stage2OutputFile << "\n";
                else if(stage == 3) stage3OutputFile << "\n";
            }
        }

Here stage1Triangles,stage2Triangles and stage3Triangles have been declared and computed elsewhere. stage1OutputFile,stage2OutputFile and stage3OutputFile are all std::ofstream.

As you can see, the code looks rather ugly, especially inside the nested for loop. How can I redirect output to the desired file dynamically so that I don't have to deal with them in if-else blocks? I want something similar to this:

// declare a stageTriangles and ofstream pair
if(stage == 1) set the pair to stage1Triangles and stage1OutputFile
else if(stage == 2) set the pair to stage2Triangles and stage2OutputFile
else if(stage == 3) ...

I tried:

std::ofstream stageOutputFile;

            if(stage == 1){
                stageTriangles = stage1Triangles;
                stageOutputFile = stage1OutputFile;
            }

but it produces an error. What am I doing wrong and how can I do it efficiently?


Solution

  • You just need to use some type of inderection.

    Pointer:

     std::ofstream *stageOutputFile;
    
     if (stage == 1) {
         stageOutputFile = &stage1OutputFile;
     }
    
     *stageOutputFile << ...;
    

    Array:

    std::ofstream& stageOutputFile[] = {stage1OutputFile, stage2OutputFile, stage3OutputFile};
    
    stageOutputFile[stage] << ...
    

    Or some other method...