Я пытаюсь использовать freopen () для печати в текстовый файл и на экран, но я только достигаю печать в файл.
Мне было интересно, можно ли было легко сохранить вывод программ в файл и распечатать его на экране? Потому что у меня все было по-другому, но мне пришлось распечатывать каждое утверждение дважды. Один для файла, другой только для вывода.
Примечание: я новичок в C ++ и пытаюсь выучить его на уроке в следующем семестре, поэтому нужен прямой ответ, так как я уже посмотрел онлайн и, кроме того, не смог найти простых ответов на это решение.
Вот что у меня так далеко:
#include<iostream>
#include<time.h>
#include<stdlib.h>
#include<fstream>
using namespace std;
void menu(){
cout << "\t********************************************************\n"<< "\t* Welcome to slot machine. *\n"<< "\t* Would you like to play? (1 to play, 2 not to play) *\n"<< "\t********************************************************\n\n";
return;
}
void update(int arr[], int &token) {
if (arr[0]==arr[1] && arr[1]==arr[2]) {
token+=4;
cout << "You win\n\n";
} else if (arr[0]==arr[1] || arr[1]==arr[2] || arr[0]==arr[2]) {
token+=1;
cout << "You got two out of three\n\n";
} else {
token-=1;
cout << "You lose\n\n";
}
}
int main() {
freopen("file.txt", "w", stdout);
int x, arr[3], token=4;
srand(time(0));
menu();
cin >> x;
while(token!=0) {
cout << "You have " << token << " tokens\n\n"<< "Pull? (1 to pull, 2 not to pull)\n\n";
cin>>x;
if(x==1) {
for(int i=0; i<3; i++) {
arr[i]=1+rand()%10;
}
cout << "\t\t";
for(int j=0; j<3; j++) {
cout << arr[j] << " ";
}
cout << "\n\n";
update(arr,token);
}
else{
cout << "OK\n";
}
}
cin.get();
return 0;
}
Я не знаю простого способа добиться этого, но мне удалось как-то решить это.
Используя fstreams, вы можете выводить в файл так же, как вы можете писать в консоль.
#include <fstream>
int main()
{
std::ofstream f("file.txt");
f << "something";
}
Теперь мы можем начать: есть ли способ вывести на консоль и файл одновременно?
Я недавно написал потоковый демультиплексор для решения этой проблемы:
#include <vector>
#include <ostream>
class stream_demultiplexer
{
private:
typedef std::vector<std::ostream*> str_cont;
str_cont d;
public:
stream_demultiplexer& put(std::ostream::char_type ch)
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(*it)->put(ch);
return *this;
}
stream_demultiplexer& write(const std::ostream::char_type* s, std::streamsize count)
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(*it)->write(s, count);
return *this;
}
stream_demultiplexer& flush()
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(*it)->flush();
return *this;
}template<typename T>
stream_demultiplexer& operator<<( const T& obj )
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(**it) << obj;
return *this;
}
stream_demultiplexer& operator<<(std::ios_base& (*func)(std::ios_base&))
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(**it) << func;
return *this;
}
template<typename CharT, typename Traits>
stream_demultiplexer& operator<<(std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&) )
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(**it) << func;
return *this;
}
stream_demultiplexer& operator<<(std::ostream& (*func)(std::ostream&) )
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(**it) << func;
return *this;
}
void add_stream(std::ostream& ss)
{
d.push_back(&ss);
}
};
Вы можете использовать это так:
stream_demultiplexer spl;
std::ofstream f("file.txt");
spl.add_stream(f);
spl.add_stream(std::cout);
spl << 55 << " HELLO WORLD";
У моего подхода есть преимущество в том, что манипуляторы и неформатированный вывод работают правильно:
spl << 76 << " " << std::hex << 76 << std::endl;
spl.put('a');
spl.write("ABCDE", 5);
Самый простой способ в UNIX-подобной среде — использовать команду оболочки tee
:
$ my-program | tee output.txt
скопирует стандартный вывод в терминал, а также в файл output.txt
,
Если вам нужно сделать это в коде, вы можете использовать свой собственный поток вывода вместо cout
, который направляет каждый operator<<
до двух (или более) ostreams
, Это кажется мне приятнее (чем мне), чем копаться с выходным файлом C, лежащим в основе ostream C ++ cout
,
#include <ostream>
class Tee {
std::ostream &first, &second;
template<typename T> friend Tee& operator<< (Tee&, T);
public:
Tee(std::ostream &f, std::ostream &s) : first(f), second(s) {}
};
template <typename T>
Tee& operator<< (Tee &t, T val)
{
t.first << val;
t.second << val;
return t;
}
Затем, если вы замените свою строку freopen на:
std::ofstream outfile("file.txt");
Tee tee(std::cout, outfile);
Вы можете просто использовать tee <<
вместо cout <<
,
Обратите внимание, что вам нужно либо пройти tee
в ваши функции, или сделать его глобальным, чтобы это работало.