Практическое решение - взять то, что работает, и обобщить это. Что работает, так это вывод, сгенерированный std::cout
, поэтому все, что требуется, это написать функцию, которая принимает поток и выполняет именно то, что делает std::cout
.
Способ сделать это состоит в том, чтобы понять, что std::ostream
является базовым классом для выходных потоков, поэтому все, что нужно, это использовать полиморфизм и написать функцию, которая принимает ссылку на std::ostream
.
Вот пример:
#include <iostream>
#include <string>
#include <ostream>
#include <fstream>
#include <sstream>
#include <cassert>
using namespace std;
void pyramid(int rows, std::ostream& );
int main()
{
// use regular cout
std::cout << "Using cout \n\n";
pyramid(8, std::cout);
// try file printing
std::ofstream fout;
fout.open("output_diamond.txt");
pyramid(8, fout);
// try printing to a string stream
std::cout << "\n\nUsing ostringstream \n\n";
std::ostringstream ostrm;
pyramid(8, ostrm);
std::cout << "\n";
std::cout << ostrm.str();
return 0;
}
void pyramid(int rows, std::ostream& sout)
{
int space = rows - 1;
for (int i = 1; i <= rows; i++) {
for (int count = 1; count <= space; count++) {
sout << ' ';
}
for (int count = 1; count <= (2 * i) - 1; count++) {
sout << '*';
}
sout << endl;
space--;
}
space = 1;
for (int i = 1; i <= rows - 1; i++) {
for (int count = 1; count <= space; count++) {
sout << ' ';
}
for (int count = 1; count <= (2 * (rows - i)) - 1; count++) {
sout << '*';
}
sout << endl;
space++;
}
}
Живой пример, показывающий std :: cout и std :: ostringstream
А вот и вывод из файла:
*
***
*****
*******
*********
***********
*************
***************
*************
***********
*********
*******
*****
***
*