如何用C ++将控制台数据写入文本文件?

时间:2010-07-20 10:37:17

标签: c++ visual-c++ cmd console-application

我正在使用C ++编写文件共享应用程序。我想将控制台输出写入一个单独的文件,同时我也希望在控制台中看到输出。任何人都可以帮助我...提前致谢。

4 个答案:

答案 0 :(得分:2)

我们走了......

#include <fstream>
    using std::ofstream;
#include <iostream>
    using std::cout;
    using std::endl;

int main( int argc, char* argv[] )
{
    ofstream file( "output.txt" ); // create output file stream to file output.txt
    if( !file ) // check stream for error (check if it opened the file correctly)
        cout << "error opening file for writing." << endl;

    for( int i=0; i<argc; ++i ) // argc contains the number of arguments
    {
        file << argv[i] << endl; // argv contains the char arrays of commandline arguments
        cout << argv[i] << endl;
    }
    file.close(); // always close a file stream when you're done with it.

    return 0;
}

PS:好的,读错了你的问题(控制台输出/输入混音),但你仍然明白我的想法。

答案 1 :(得分:2)

这个想法是创建一个std :: streambuf的派生,它将数据输出到文件和cout。然后创建它的一个实例并使用cout.rdbuf(...);

这是代码(使用MSVC ++ 2010测试,应该适用于任何编译器):

class StreambufDoubler : public std::streambuf {
public:
    StreambufDoubler(std::streambuf* buf1, std::streambuf* buf2) :
            _buf1(buf1), _buf2(buf2), _buffer(128)
    {
        assert(_buf1 && _buf2);

        setg(0, 0, 0);
        setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
    }

    ~StreambufDoubler() {
        sync();
    }

    void imbue(const std::locale& loc) {
        _buf1->pubimbue(loc);
        _buf2->pubimbue(loc);
    }

    std::streampos seekpos(std::streampos sp, std::ios_base::openmode which) {
        return seekoff(sp, std::ios_base::cur, which);
    }

    std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which) {
        if (which | std::ios_base::in)
            throw(std::runtime_error("Can't use this class to read data"));

        // which one to return? good question
        // anyway seekpos and seekoff should never be called
        _buf1->pubseekoff(off, way, which);
        return _buf2->pubseekoff(off, way, which);
    }

    int overflow(int c) {
        int retValue = sync() ? EOF : 0;
        sputc(c);
        return retValue;
    }

    int sync() {
        _buf1->sputn(pbase(), pptr() - pbase());
        _buf2->sputn(pbase(), pptr() - pbase());
        setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
        return _buf1->pubsync() | _buf2->pubsync();
    }

private:
    std::streambuf*     _buf1;
    std::streambuf*     _buf2;

    std::vector<char>   _buffer;
};


int main() {
    std::ofstream myFile("file.txt");
    StreambufDoubler doubler(std::cout.rdbuf(), myFile.rdbuf());
    std::cout.rdbuf(&doubler);

    // your code here

    return 0;
}

但请注意,更好的实现会使用模板,streambufs列表而不是两个,等等。但我希望尽可能简单。

答案 2 :(得分:1)

您实际想要的是实时跟踪添加到应用程序写入的日志中的行。

在Unix世界中,有一个简单的工具具有这个功能,它被称为tail

调用tail -f your_file,您将在控制台中看到几乎实时显示的文件内容。

不幸的是,tail不是Windows中的标准工具(根据你问题的标签,我认为你正在使用它)。 但是,它可以在GnuWin32包中找到,也可以在MSYS中找到。

还有一些Windows的本机工具具有相同的功能,我个人使用的是Tail For Win32,它是根据GPL许可的。

因此,总而言之,我认为您的程序不应该将相同的数据输出到不同的流,因为它可能会在没有实际好处的情况下减慢速度,而已经建立了专门用于解决该问题的工具,而不需要发展任何东西。

答案 3 :(得分:0)

我不用c ++编程,但这是我的建议:创建新类,它接受InputStream(c ++或smth中的istream),而不是每个传入的字节,它将在std.out和文件中传输。
我确信有一种方法可以改变前面提到的类的标准输出流。我记得,std.out是cout的某种财产 再一次,我在半年多的时间里花了一个星期的时间用c ++,所以我所说的都是垃圾。