0

so if I have a simple interactive program like this:

#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#define cout os

int main() {

    stringstream os;

    cout << "If you would like to continue, type 'Continue'" << '\n';

    string line;
    while (cin >> line) {

        if (line == "Continue") {
            cout << "If you would like to continue, type 'Continue'" << '\n';
        }

        else { break; }
    }

    cout << "Program ended." << '\n';

    cout << os.str();
    return 0;
}

How do I make it such that I am able to include my directive "#define" so that all the lines printed to standard output will be printed at the end of the program by cout << os.str(), when by doing so it also will be making the final "cout" into an "os"? I have tried using printf instead with the os at the end and have been having trouble/compiler errors saying "no matching function call to printf."

I hope my question makes sense and apologize if this has been asked already but I have been unable to find it on here.

user313
  • 681
  • 1
  • 8
  • 21
  • You generally want to avoid `#define` in C++. That's the easy part. I'm not sure what you're trying to do. Maybe you should show what you've tried? You'd probably need to pass `os.str().c_str()` to `printf()`. – Jonathan Leffler Mar 04 '16 at 18:00
  • 2
    I don't understand what you are trying to accomplish. Use `std::cout` if you want to write to stdout, use `std::ostringstream` if you want to save output in a string. Don't use `#define cout os` because it's evil. – Christian Hackl Mar 04 '16 at 18:01
  • Is your question "can I make it so that all output to `std::cout` is also collected in my `stringstream`" or do you want to use your `stringstream` instead of `std::cout`? – molbdnilo Mar 04 '16 at 18:02
  • 2
    Your question also does not make sense because much of your output is prompts for the user to give input, so *waiting* to display those until the end of the program won't tell the user what to do. – crashmstr Mar 04 '16 at 18:14

2 Answers2

2

You don't need (respectively want) a preprocessor macro to achieve this. Just put the code you want to print out into a function:

void writeToStream(std::ostream& os) {
    os << "If you would like to continue, type 'Continue'" << '\n';

    string line;
    while (cin >> line) {

        if (line == "Continue") {
             os << "If you would like to continue, type 'Continue'" << '\n';
        }

        else { break; }
    }

    os << "Program ended." << '\n';
}

And call it from main() as needed:

int main() {
#ifdef TOSCREEN
    writeToStream(cout);
#else
    std::stringstream os;
    writeToStream(os);
#endif
    cout << os.str();
    return 0;        
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

It's bad practice to use names from the STL as precompiler definitions. If what you want is to redirect the std::cout to your std::stringstream then you can do it by using std::cout::rdbuf in the following way:

#include <iostream>
#include <sstream>
#include <string>
#include <cstring>

using namespace std;

int main() {
    stringstream os;

    // redirect cout to os
    auto prv = cout.rdbuf(os.rdbuf());

    cout << "If you would like to continue, type 'Continue'" << '\n';

    string line;
    while (cin >> line) {

        if (line == "Continue") {
            cout << "If you would like to continue, type 'Continue'" << '\n';
        }

        else { break; }
    }

    cout << "Program ended." << '\n';

    // restore cout to its original buffer
    cout.rdbuf(prv);

    cout << os.str();

    return 0;
}
101010
  • 41,839
  • 11
  • 94
  • 168