Использование директив препроцессора с cout и stringstream в интерактивной программе - C++

Так что, если у меня есть простая интерактивная программа, как это:

#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;
}

Как мне сделать так, чтобы я мог включить свою директиву "#define", чтобы все строки, напечатанные на стандартный вывод, были напечатаны в конце программы cout << os.str(), когда это делается это также будет превращать заключительный "cout" в "os"? Я попытался использовать printf вместо операционной системы os в конце, и у меня возникли проблемы / ошибки компилятора, говорящие "нет соответствующего вызова функции для printf".

Я надеюсь, что мой вопрос имеет смысл и прошу прощения, если он уже был задан, но я не смог найти его здесь.

2 ответа

Вам не нужно (соответственно, хотите) макрос препроцессора для достижения этой цели. Просто поместите код, который вы хотите распечатать, в функцию:

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';
}

И позвони из main() по мере необходимости:

int main() {
#ifdef TOSCREEN
    writeToStream(cout);
#else
    std::stringstream os;
    writeToStream(os);
#endif
    cout << os.str();
    return 0;        
}

Это плохая практика - использовать имена из STL в качестве определений прекомпилятора. Если вы хотите перенаправить std::cout на ваш std::stringstream тогда вы можете сделать это с помощью std::cout::rdbuf следующим образом:

#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;
}
Другие вопросы по тегам