【问题标题】:How can the Lambda expression be modified to put output in text file?如何修改 Lambda 表达式以将输出放入文本文件?
【发布时间】:2019-11-12 18:23:29
【问题描述】:

我有一个代码,我可以用它在屏幕上显示输出。但是,我想把输出放在一个文本文件中。坦率地说,我读过 Lambda 表达式,但我很难理解它的功能(因为我是初学者)。

#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
#include <vector>
using Matrix = std::vector<std::vector<float>>;

void addRow(Matrix& M, const int rowNum, const int id, const float type, const float x, const float y,const float z) {
    M[rowNum][0] = id;
    M[rowNum][1] = type;
    M[rowNum][2] = x;
    M[rowNum][3] = y;
    M[rowNum][4] = z;
}

int main() {
    string line;
    float x0, y0, z0, x1, y1, z1, type;
    int NUMBER_line=0, id=0,NUMBER_line1=0,NUMBER_line3=0;

    ofstream secondoutput;                  // the output text file
    secondoutput.open ("secondoutput.txt"); // the output text file

    ifstream myfile("1.lammpstrj");
    string namefile;
    if (myfile.is_open()) {
        for (int lineno = 0; getline(myfile, line) && lineno < 7; lineno++) {
            if (lineno == 2)  myfile >> NUMBER_line;
        }
        cout << " NUMBER_line: " << NUMBER_line << endl;

        Matrix Input0(NUMBER_line, std::vector<float>(5));
        for (float linenoq = 0; getline(myfile, line) && linenoq < NUMBER_line; linenoq++) {
            myfile >> id >> type >> x0 >> y0 >> z0;
            addRow(Input0, linenoq, id, type, x0, y0, z0);

        }


        for (int i=0; i <3; i++){
            for (int lineno = 0; getline(myfile, line) && lineno < 7; lineno++) {
                if (lineno == 2)  myfile >> NUMBER_line1;
            }


            Matrix Input1(NUMBER_line1, std::vector<float>(5));
            for (int linenoq = 0; getline(myfile, line) && linenoq < NUMBER_line1; linenoq++) {
                myfile >> id >> type >> x1 >> y1 >> z1;
                addRow(Input1, linenoq, id, type, x1, y1, z1);

            }

            Matrix Output(NUMBER_line, std::vector<float>(5));
            for (size_t row = 0; row < Output.size(); ++row) {
                for (size_t col = 0; col < Output[0].size(); ++col) {
                    if (col < 2) {
                        Output[row][col] = Input0[row][col];
                    }
                    else {
                        Output[row][col] = Input1[row][col] - Input0[row][col] ;
                    }
                }
            }

            std::for_each(Output.cbegin(), Output.cend(),
            [](auto const& row) {
                std::for_each(row.cbegin(), row.cend(),
                    [](const float value) { 
                        cout << value << " "; 
                        secondoutput << value << " "; // the output text file
                        });
                cout << endl;
                secondoutput << "\n" ; // the output text file

            });
        }
        secondoutput.close();
    }
    else cout << "Unable to open file";
    return 0;
}

我可以请求帮助吗?我想要一个输出文本文件,就像输出在屏幕上写的那样。 看来最重要的事情是关于我放置“secondoutput &lt;&lt; value &lt;&lt; " ";”和“secondoutput &lt;&lt; "\n" ;”的位置。

我不知道他们应该在哪里。我总是将“secondoutput &lt;&lt; value &lt;&lt; " ";”放在其他代码中,它们运行良好,并给我一个输出文本文件。但是现在,我不知道为什么它们不起作用。 在此先感谢您的帮助

问候

【问题讨论】:

  • 我永远不会明白为什么有人会在这种情况下使用for_each 而不是 ranged for 循环。代替for_each 和lambda 表达式,你可以写for(const auto&amp; row : Output) {for(const auto&amp; value) {cout...; secondoutput...}}
  • @eike 如果我用 for_each 替换这些,你是我的吗,那么代码可以创建一个文本文件并将输出放入其中?

标签: c++ lambda c++14 generic-lambda


【解决方案1】:

我想要一个输出文本文件,就像输出在屏幕上写的那样。

无论如何,如果没有输入文件的内容,很难帮助您...

你的代码有问题;在你的 lambda 表达式中

        [](auto const& row) {
            std::for_each(row.cbegin(), row.cend(),
                [](const float value) { 
                    cout << value << " "; 
                    secondoutput << value << " "; // the output text file
                    });
            cout << endl;
            secondoutput << "\n" ; // the output text file
        }

您正在使用 secondoutput 而不捕获它。

要解决这个问题,可以在两个lambdas的捕获列表中添加&amp;

 // .....V  add &
        [&](auto const& row) {
            std::for_each(row.cbegin(), row.cend(),
                [&](const float value) { 
 /*   add & .....^ */ cout << value << " "; 
                    secondoutput << value << " "; // the output text file
                    });
            cout << endl;
            secondoutput << "\n" ; // the output text file
        }

这样您就可以通过引用捕获所有内容(也可以是 secondoutput)。

额外的未请求建议:请注意,正如 eike 所建议的,您可以避免捕获、lambdas 和 std::for_each(),只需使用范围 for 循环(另外 eike 建议避免多次刷新)

        for ( auto const & row : Output )
         {
           for ( auto const & value : row )
            {
              std::cout << value << ' ';
              secondoutput << value << ' ';
            }

           std::cout << '\n';
           secondoutput << '\n';
         }

       std::cout << std::flush; // you can avoid it, because you're ending the program
       secondoutput << std::flush; // you can avoid it, because you're closing the file

【讨论】:

  • 我强烈建议不要使用std::endl 换行,因为这包括每次使用时的刷新。如果您不在不稳定的环境中,只需使用'\n',您需要在程序崩溃之前获得完整的输出。标准流在销毁时刷新。
  • @eike - 好点:在外部循环的末尾添加了一个 std::flush;谢谢。
  • 编辑我的评论有点晚了。流在销毁时刷新,因此您根本不需要显式刷新。
  • @eike - 另一个好点;这次我将它添加为注释(假设我展示了一个程序片段......也许有人可以将它复制到更复杂的代码中,std::flush 可能会有用)。
  • 亲爱的@max66 非常感谢您对我的帮助。还有你提到了哪些好的 cmets 和 "eike" 换行
猜你喜欢
  • 2022-12-11
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多