6

要件があり、データを使用printfcoutて表示する必要がありconsole and fileます。printf私はそれをしましたが、私coutは苦労しています。

   #ifdef _MSC_VER
     #define GWEN_FNULL "NUL"
     #define va_copy(d,s) ((d) = (s))
         #else
         #define GWEN_FNULL "/dev/null"
        #endif
        #include <iostream>
        #include <fstream>

        using namespace std;
        void printf (FILE *  outfile, const char * format, ...) 
        {

            va_list ap1, ap2;
            int i = 5;
            va_start(ap1, format);
            va_copy(ap2, ap1);
            vprintf(format, ap1);
            vfprintf(outfile, format, ap2);
            va_end(ap2);
            va_end(ap1);
        }
    /*    void COUT(const char* fmt, ...)
        {
            ofstream out("output-file.txt");
            std::cout << "Cout to file";
            out << "Cout to file";
        }*/
        int main (int argc, char *argv[]) {

            FILE *outfile;
            char *mode = "a+";
            char outputFilename[] = "PRINT.log";
            outfile = fopen(outputFilename, mode);

            char bigfoot[] = "Hello 

World!\n";
        int howbad = 10;

        printf(outfile, "\n--------\n");
        //myout();

        /* then i realized that i can't send the arguments to fn:PRINTs */
        printf(outfile, "%s %i",bigfoot, howbad); /* error here! I can't send bigfoot and howbad*/

        system("pause");
        return 0;
    }

私はそれをCOUT(キャップ、上記のコードのコメント部分) で行いました。しかし、 normal を使用したいstd::coutので、どうすればオーバーライドできますか。そして、それは両方sting and variablesのように機能するはずです

int i = 5;
cout << "Hello world" << i <<endl;

または、とにかくstdoutデータをキャプチャして、簡単に書き込むこともできますかfile and console

4

9 に答える 9

4

基になるバッファーを交換できます。これは、RAII によって促進されたものです。

#include <streambuf>

class buffer_restore
{
    std::ostream&   os;
    std::streambuf* buf;
public:
    buffer_restore(std::ostream& os) : os(os), buf(os.rdbuf())
    { }

    ~buffer_restore()
    {
        os.rdbuf(buf);
    }
};

int main()
{
    buffer_restore b(std::cout);
    std::ofstream file("file.txt");

    std::cout.rdbuf(file.rdbuf());
    // ...
}
于 2013-09-24T12:30:46.453 に答える
1

std::coutと を使用しprintfて変更できないコードがあると仮定します。それ以外の場合、問題を解決する最も簡単なcout方法は、 から別のストリームに書き込みfprintfprintf.

このアプローチに従うことで、標準出力と特定のファイルの両方に実際に書き込む新しいストリーム クラスと、 と の両方への呼び出しを組み合わせた関数の両方を定義できprintfますfprintf

ただし、はるかに簡単なアプローチはtee、元は UNIX のプログラムを使用することです。このプログラムは、入力を出力と特定のファイルの両方にコピーします。これにより、次の方法でプログラムを簡単に呼び出すことができます。

your_program | tee your_log_file

この質問への回答は、Windows で利用可能ないくつかの代替実装につながります。個人的には、UNIX/Linux ユーティリティを利用できるようにするために、常に PC にcygwinをインストールしています。

于 2013-09-24T07:45:29.793 に答える
0

私が正しく推測した場合、出力に送られるすべてをファイルにも記録する必要があります。

必要なのはオブザーバーパターンです。

コード内のすべての直接ログを、新しいリレーへの呼び出しに置き換えます。ロギング リレーは、メッセージをオブザーバーに送信します。オブザーバーの 1 人がメッセージを画面に記録します。もう 1 つはファイルにログを記録します。可能であれば、リレーをシングルトンにすることは避けてください。

この提案は、すべてのソース ファイルを編集できる場合にのみ機能します。

于 2013-09-24T08:15:57.260 に答える
0

std::coutファイルへの書き込みstdoutLinux および Windows では次のことができます

#include <stdio.h>
#include <iostream>



int main()
{
    freopen("test.txt", "w", stdout);
    std::cout << "Hello strange stdout\n";
}

元に戻すには、ここから取得した以下を使用します

#include <stdio.h>
#include <stdlib.h>

void main(void)
{
   FILE *stream ;
   if((stream = freopen("file.txt", "w", stdout)) == NULL)
      exit(-1);

   printf("this is stdout output\n");

   stream = freopen("CON", "w", stdout);

   printf("And now back to the console once again\n");
}

注: 後者は Windows のみです。

于 2013-09-24T09:35:48.927 に答える
-1

これにはすでに Boost クラスがあります。tee

于 2013-09-24T14:41:36.433 に答える
-1

マクロを使用してみてください-次のようなものです(インクルードを追加する必要があります):

#define MY_COUT(theos,printThis) { cout << printThis ; theos <<  printThis; }

void test()
{
     ofstream myos;
    myos.open("testfile", ios::trunc|ios::out);
    int i = 7;
    MY_COUT(myos, "try this numbers" << i << i + 1 << endl);
    myos.close()
}
于 2013-09-24T08:01:10.243 に答える