-1

I'm a C++ newbie and am wanting to save outputs that are printed when looping over several files. The outputs are 3 floats, which are called mass_pole, sum, and sum_SM. How do I save these looped outputs (without overwriting them) to a .txt file using the proper C++ tabs / new line semantics. I'm wanting something like:

//mass_pole    //sum        //sum_SM
200            2300.2       713.4
250            2517.3       1231.77
300            2110.5       432.5

inside a .txt file (without the headers).

My code so far is below, but I don't think this is correct for my aforementioned desire. Specifically, I need help with L25 onward. Any advice would be much appreciated!

// root -l aTGCs_test.C                                                                                                                                                                         
#include <iostream>
#include <fstream>
#include <string>
#include "TMath.h"

using namespace std;


void masspoleweights(TString file, TString mass_pole) {

  TChain* myTrees = new TChain("Events");

 [. . .]

  for (int j = 0; j < myTrees->GetEntries(); ++j){
  //for (int j = 0; j < 1000; ++j){                                                                                                                                                             
    myTrees->GetEntry(j);

    sum=variable1;
    sum_SM=variable2;

  }

L25>>  ofstream myfile ("weights.txt");

  //saving outputs to file (three outputs that loop by mass: mass, sum, pdfweights)

  for (int i = 0; i < 200; ++i){
    myfile << mass_pole << sum << sum_SM << std::endl;
  }
}
Phoenyx
  • 1
  • 2
  • 2
    You'll want to use the *append* feature of `ofstream`. And you'll want to change `myfile << mass_pole << sum << sum_SM << std::endl;` to `myfile << mass_pole << "\t" << sum << "\t" << sum_SM << "\n";` – Eljay Aug 15 '22 at 16:39
  • what about a csv? unless you're sure about the data, the format would most likely goes wrong. – apple apple Aug 15 '22 at 16:40
  • Tactical note: In `for (int i = 0; i < 200; ++i)`, 200 is what we call a [magic number](https://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad). 200 doesn't really mean much by itself, you can't look at the code and go, "Why that's the number of items in the list!" quite as easily as you could with a variable (or constant) named `number_items`, and it can be tricky to ensure that you always have exactly 200 items to print. – user4581301 Aug 15 '22 at 16:44
  • @Eljay Well, for single characters I'd rather prefer character literals: `'\t'`/`'\n'` – gaining (just) a minimum of efficiency, but for free... – Aconcagua Aug 15 '22 at 16:46
  • 2
    What is the intended consumer? If it is human eyes manually sizing the columns with [`std::setw`](https://en.cppreference.com/w/cpp/io/manip/setw) is often better than using tabs because the size of tab is inconsistent across viewing software. If the intended consumer is a computer program, the tab character `'\t'` is usually better because it's easier to parse. – user4581301 Aug 15 '22 at 16:47
  • Hi, @Eljay! Thank you for the change. I've replaced that part. Would you be willing to be more specific on the append feature of `ofstream`? Right now I'm attempting: ``` for (int i = 0; i < 200; ++i){ std::ofstream::append; myfile << mass_pole << sum << sum_SM << std::endl; } ``` But, should I do an open function first, or ensure that the file is open? – Phoenyx Aug 15 '22 at 16:57
  • Use *openmode* [`app`](https://en.cppreference.com/w/cpp/io/ios_base/openmode) to append to the file. – Eljay Aug 15 '22 at 17:04
  • Side note: The stream state should be checked after every IO transaction to ensure the transaction completed successfully. All sorts of things could go wrong, and if you don't check and handle sooner or later you'll have waste time debugging. – user4581301 Aug 15 '22 at 17:13
  • @user4581301 you're right--I am changing that maximum. This is meant for post-processing using another script, so computer-eyes will work just fine. Thanks! – Phoenyx Aug 16 '22 at 10:08

1 Answers1

0

As per the help of all the experts in the comments section, here is the final code that works:

  ofstream myfile ("weights.txt", ios::in | ios::out | ios::app); //file open mode (READ), WRITE, append                                                                                                                      

  //loop over all outputs to save in a txt file (no overwrites):                                                                      
  for (int i = 0; i < 1; ++i){
    ofstream::ios_base::app;
    myfile << mass_pole << "\t"  << sum << "\t" << sum_SM << "\n";
}
Phoenyx
  • 1
  • 2