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

时间:2019-07-12 06:21:53

标签: c++ ofstream

我有一个Matrix类和一个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;
            }

但是会产生错误。我在做什么错,我该如何有效地做呢?

3 个答案:

答案 0 :(得分:4)

我会尝试为您指出大致方向:

创建常规功能

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

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

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

答案 1 :(得分:1)

您只需要使用某种类型的独立性即可。

指针:

 std::ofstream *stageOutputFile;

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

 *stageOutputFile << ...;

数组:

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

stageOutputFile[stage] << ...

或其他方法...

答案 2 :(得分:1)

我会考虑使用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";
    }
}