简体   繁体   中英

C++ Writing to file or console by argument

Ok, so I would like to do something I myself do find rather interseting .. I want an optional argument in my function and this argument would do two things; 1. Decide whether the text is being printed to the console or to a file 2. Print it to a file if that's the case, otherwise to console

I want it to be in the same function because I want very efficient code. This is how I tried to solve it but obviously doesn't work

void Maze::Print_maze(std::string file = "no!ne") const{
    if (file != "no!ne")
        std::ofstream outfile(file);
    for (int i = 0; i < Map.size(); i++)
    {
        for (int j = 0; j < Map[i].size(); j++)
        {
            if (file == "no!ne")
                std::cout << Map[i][j];
            else
                outfile << Map[i][j];
        }
        if (file == "no!ne")
            std::cout << std::endl;
        else
            outfile << std::endl;
    }
}

For the curious ones .. The code is from a maze project I'm working on, I'm generating a randomized maze, solving it and there's also the possibility of reading a maze from a file then solving it. Now all that remains is to print it to a file. But as said, rather than making two functions, I'd like to merge my normal print to console with print to a file. I'm just wondering how .. Is it possible? My "Map[][]" is a vector <vector<char> >

void Maze::Print_maze(std::ostream& s = std::cout)

然后只传递要写入的任何流。

The best approach is to have an std::ostream* that points to an std::ofstream , if you want to write to a file, or std::cout if you want to write to the console.

std::ostream* outputTarget = &std::cout;

void output(const std::string& message)
{
    *outputTarget << message;
}

void useFileOutput()
{
    static std::ofstream outFile;
    if (!outFile.is_open())
        outFile.open("log.txt");
    outputTarget = &outFile;
}

void useCout()
{
    outputTarget = &std::cout;
}

In you situation I would make 3 function, two with the signatures you want to disambiguate and one that actually does the work. This way you get the unification of having one function do the work and the cleanliness of two functions:

public:
void Maze::Print_maze(std::ostream& OutputTarget){
   for (int i = 0; i < Map.size(); i++)
   {
       for (int j = 0; j < Map[i].size(); j++)
       {
           OutputTarget << Map[i][j];
       }
       OutputTarget << std::endl;
   }
}

void Maze::Print_maze() const{
   Print_maze(std::cout);
}

void Maze::Print_maze(std::string file) const{
   std::ofstream Output_file(file.c_str());
   Print_Maze(Output_file);
   Output_file.close();
}

Passing around references to the base types allows your maze output logic to ignore the actual output type and focus on rendering the maze.

This in some obtuse sense that is unlikely to matter would also be more performant because you would not need to make a series of string comparisons.

More importantly this version with the presentation and business(maze rendering is now a business) logic separate is simpler, therefor easier to read and less bug prone.

Thanks guys, I read your replies, I'm thankful for all the good comments and efforts you put to help me. I came to a solution and I believe this is the best solution to my problem that I can come up with. I also added a bit of error-management

void Maze::Print_maze(std::string file) const{
    std::ofstream outfile(file);
    // if file is open, write to file otherwise write to console
    std::ostream &out= (!outfile.is_open()? std::cout : outfile);
    // Check if file failed to open
    if(file != "" && (!outfile.is_open()))
        std::cerr << "File failed to open." << std::endl;
    for (int i = 0; i < Map.size(); i++)
    {
        for (int j = 0; j < Map[i].size(); j++)
        {
                out << Map[i][j];
        }
            out << std::endl;
    }
    if(outfile.is_open())
        outfile.close();
}

Edit: Forgot to mention this .. My Maze.h file with my class consists of this function declaration:

void Print_maze(std::string file = "") const;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM