1

I am trying to write some code that is going to output a speed and time values to multiple files, specifically 4 different files which represents 4 different objects moving.

I know that to open and write to 1 file I can do the following:

#include <iostream>
#include <fstream>  

std::ofstream outfile ("test.txt");

outfile << "my text here!" << std::endl;

outfile.close();

However I need to adapt this such that it would work in a switch statement as follows:

for (int i = 0; i < numRobots; i++){
    switch (i){
        case 0: 
            if (r1_stop == 1) r1Speed = 0; 
            else //Update speed
            r1File << r1Speed << " " << time << endl;
        case 1: 
            if (r2_stop == 1) r2Speed = 0; 
            else //Update speed
            r2File << r2Speed << " " << time << endl;
        case 2: 
            if (r3_stop == 1) r3Speed = 0; 
            else //Update speed
            r3File << r3Speed << " " << time << endl;
        case 3:
            if (r4_stop == 1) r4Speed = 0; 
            else //Update speed
            r4File << r4Speed << " " << time << endl;
    }
}

Where r1File, r2File, r3File, and r4File are the files containing the speed and time for the respective objects. Im not quite sure how to implement this type where I have multiple files open or do i have to keep opening and closing the files? Im worried about overwriting existing data in the file if that is the case unless it knows to not start from the beginning of the file when opening it again.

Any help is appreciated, thanks

Javia1492
  • 862
  • 11
  • 28
  • 1
    Why not use arrays? You basically have the same code written 4 times, with the only difference being `1`, `2`, `3`, etc. Then the code becomes a 3 line `for` loop with no `switch`. – PaulMcKenzie Mar 18 '17 at 05:06
  • Also, don't end each file write with a `<< endl` This will do a buffer flush to the file and is quite slow. Prefer using `<< '\n'` – doug Mar 18 '17 at 06:27
  • @PaulMcKenzie Well it because r1_stop, etc.. are SystemC signals, `sc_in r1_stop;` So i wouldnt be able to define them as an array since they are coming from another `SC_MODULE` – Javia1492 Mar 18 '17 at 20:47
  • @Javia1492 Then use another data structure, such as a `std::vector` or `std::map`. If there were 100 different return values, you would write a switch with 100 cases? A good programmer identifies code duplication, and adjusts the code accordingly. It may not be as simple as an array, but it can still be refactored into something that is maintainable.. – PaulMcKenzie Mar 18 '17 at 21:29
  • @PaulMcKenzie Well, im kind of forced to use those signals. The only other option is to make an extra data structure like you mentioned but that still doesnt change the end result since i still need to identify which object im referencing to determine if i need to set its corresponding signal so send it to another module. – Javia1492 Mar 18 '17 at 21:37
  • Use a `std::map` that associates the signal with the information about that signal. Then use `std::map::find` to get the proper information, given a signal sent. The initial setup of the map is all that needs to be done, but once that is done, you're not writing for-loops with switch-case statements all over the place identifying the signal. – PaulMcKenzie Mar 18 '17 at 21:43

1 Answers1

1

By default std::ofstream overwrites instead of appends, so from the moment you open the file it will be streaming bytes in that overwrite whatever was there before it was opened.

*fstream variants keep a file open until the stream object is destroyed. In other words a file being open is tied to the lifetime of the *fstream object representing it. Once destroyed, the file is immediately closed. This concept is known as RAII. In your case the stream objects are global, and thus are destroyed after main() ends, right before the application terminates.

If writing to the files isn't time critical, your implementation is good enough. On the other hand if you need more accurate measurements, consider writing each of your outputs to an intermediate buffer such as std::stringstream, then stream that data to your files after you're done taking measurements.

However, if you don't need the data from previous application runs, don't bother using files and instead just write to memory using a std::stringstream.

Community
  • 1
  • 1
Koby Duck
  • 1,118
  • 7
  • 15