在要写入的输出文件之间动态选择

Dynamically choose between output file to write

我有一个 Matrix class 和一个 std::vector<Matrix>。我也有 3 个计算阶段,每个阶段都会产生一个 std::vector<Matrix>,我必须将这些矩阵向量写入 stage1.txtstage2.txtstage3.txt。我为此编写了一个函数,它将 stage 数字作为参数并将 Matrix 的向量输出到相应的文件。目前我的代码如下所示:

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";
            }
        }

此处 stage1Trianglesstage2Trianglesstage3Triangles 已在别处声明和计算。 stage1OutputFilestage2OutputFilestage3OutputFile都是std::ofstream

如您所见,代码看起来相当丑陋,尤其是在嵌套的 for 循环中。 如何动态地将输出重定向到所需的文件,这样我就不必在 if-else 块中处理它们? 我想要类似这样的东西:

// 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) ...

我试过了:

std::ofstream stageOutputFile;

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

但它会产生错误。我做错了什么,我怎样才能有效地做到这一点?

你只需要使用某种间接的方式。

指针:

 std::ofstream *stageOutputFile;

 if (stage == 1) {
     stageOutputFile = &stage1OutputFile;
 }

 *stageOutputFile << ...;

数组:

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

stageOutputFile[stage] << ...

或其他一些方法...

我会尽量给你指出大致的方向:

创建通用函数

此函数可以将任何 std::vector<Matrix> 打印到任何 std::ostreamstd::ostream 是所有输出流的基础 class。可能类似于 void PrintListOfMatrices(const std::vector<Matrix> &matrices, std::ostream &output) {...}

为每对向量调用它并输出:

PrintListOfMatrices(stage1Triangles, stage1OutputFile);
PrintListOfMatrices(stage2Triangles, stage2OutputFile);
PrintListOfMatrices(stage3Triangles, stage3OutputFile);

我会考虑使用 lambda 创建对 stageTriangles 的引用(您在代码中复制了一份,可能是一个大型数据结构)和 stageOutputFile。

引用优于指针,因为对象不是可选的。如果指向 stageTriangle 或输出文件的指针是 NULL.

,则此代码将失败
void writeTrianglePointsToFile(int stage) {
    auto getStageTriangles = [&](int stage) {
        if (stage == 1) {
            return stage1Triangles;
        } else if (stage == 2) {
            return stage2Triangles;
        } else if (stage == 3) {
            return stage3Triangles;
        }
    };
    auto getStageOutputFile = [&](int stage) {
        if (stage == 1) {
            return stage1OutputFile;
        } else if (stage == 2) {
            return stage2OutputFile;
        } else if (stage == 3) {
            return stage3OutputFile;
        }
    };

    const auto& stageTriangles = getStageTriangles(stage);
    const auto& stageOutputFile = getStageOutputFile(stage);

    for (const auto& stageTriangle : stageTriangles) {
        int rows = stageTriangle.getMatrixRows() - 1;  // discard last row
        int columns = stageTriangle.getMatrixColumns();
        for (int j = 0; j < columns; j++) {
            for (int k = 0; k < rows; k++) {
                stageOutputFile << std::fixed << std::setprecision(7) << std::showpoint << stageTriangle.matrix[k][j];
                if (k != rows - 1)
                    stageOutputFile << " ";
            }
            stageOutputFile << "\n";
        }
        stageOutputFile << "\n";
    }
}