Save Std::Cout in File

Asked

Viewed 149 times

0

I need to adapt some program outputs Ripser. More precisely, I need to do the following:

1. running the program in an example, we have:

./ripser examples/random16.lower_distance_matrix 

whose output is

distance matrix with 15 points
value range: [1,120]
persistence intervals in dim 0:
 [0,1)
 [0,2)
 [0,4)
 [0,5)
 [0,6)
 [0,7)
 [0,8)
 [0,9)
 [0,10)
 [0,11)
 [0,12)
 [0,14)
 [0,15)
 [0,35)
 [0, )
persistence intervals in dim 1:
 [54,56)
 [43,45)
 [37,51)
 [27,56)
 [22,52)
 [21,52)
 [20,59)
 [19,62)
 [18,62)
 [17,60)
 [16,33)

2. have interest only at the exits of the interval form, i.e., [a,b) or [a, ). I would like to save them to a file (eg. output.txt).

3. Analyzing the code .cpp I searched all the lines that contain [ , ), which I present below.

l. 639   std::cout << " [" << diameter << ", )" << std::endl << std::flush;
l. 651   std::cout << " [" << diameter << "," << death << ")" << std::endl << std::flush;
l. 929   if (get_diameter(e) > 0) std::cout << " [0," << get_diameter(e) << ")" << std::endl;
l. 939   if (dset.find(i) == i) std::cout << " [0, )" << std::endl << std::flush;

4. I note that some outputs occur within a loop, for example that of line 939, which can provide several intervals of the shape [ , ), depending on the input file used. Here is the loop block:

#ifdef PRINT_PERSISTENCE_PAIRS
        for (index_t i = 0; i < n; ++i)
            if (dset.find(i) == i) std::cout << " [0, )" << std::endl << std::flush;
#endif

My attempt

For each of the 4 lines mentioned above, I used the code below to write the output in a file, changing only the format within the fprintf(fp, " ").

//! [write to file]
FILE * fp;
fp = fopen ("./output", "a+");
fprintf(fp, "0 0 -1\n");
fclose(fp);

This has worked almost well, except for the fact that within the loop, only one line is written in the output, even in the examples where they occur on the screen repeatedly.

Here’s the loop block, adapted.

#ifdef PRINT_PERSISTENCE_PAIRS
        for (index_t i = 0; i < n; ++i)
            if (dset.find(i) == i)
                std::cout << " [0, )" << std::endl << std::flush;
                //! [write to file]
                FILE * fp;
                fp = fopen ("./output", "a+");
                fprintf(fp, "0 0 -1\n");
                fclose(fp);
#endif

One of the outputs I had was:

0 0 1.013644
0 0 2.838865
0 0 3.131685
0 0 4.077876
0 0 4.725016
0 0 4.818406
0 0 4.924389
0 0 -1

in which we can see the last line, which occurred only once, but should have appeared a dozen times, due to the for (index_t i = 0; i < n; ++i).

Any help is welcome.

1 answer

2

If it is C++, use C++. Behold:

std::cout << " [" << diameter << ", )" << std::endl << std::flush;

then just:

#include <fstream>
// ...
std::fstream fs;
fs.open("output.txt", std::fstream::out | std::fstream::app);
fs << " [" << diameter << ", )" << std::endl;
fs.close();

The same thing that is printed on the console will be saved in the file.

Tip: in the loop create the instance of fstream and open the file before the loop, put only to write inside the loop, and close the file (Fs.close()) when exiting the loop.

  • 1

    No need to use std::flush with std::endl, since the behaviour of the second is equivalent to std::cout << '\n' << std::flush'. Speaking of which, don’t use std::endl deliberately! This intense Flushing can cause a significant drop in program performance.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.