将 cout 分配给变量名

发布于 2024-07-10 18:06:49 字数 583 浏览 8 评论 0原文

在 ANSI C++ 中,如何将 cout 流分配给变量名? 我想要做的是,如果用户指定了输出文件名,我将输出发送到那里,否则,将其发送到屏幕。 所以类似:

ofstream outFile;
if (outFileRequested) 
    outFile.open("foo.txt", ios::out);
else
    outFile = cout;  // Will not compile because outFile does not have an 
                     // assignment operator

outFile << "whatever" << endl;

我也尝试将其作为宏函数执行:

#define OUTPUT outFileRequested?outFile:cout

OUTPUT << "whatever" << endl;

但这也给了我一个编译器错误。

我想我可以为每个输出使用 IF-THEN 块,但如果可以的话我想避免这种情况。 有任何想法吗?

In ANSI C++, how can I assign the cout stream to a variable name? What I want to do is, if the user has specified an output file name, I send output there, otherwise, send it to the screen. So something like:

ofstream outFile;
if (outFileRequested) 
    outFile.open("foo.txt", ios::out);
else
    outFile = cout;  // Will not compile because outFile does not have an 
                     // assignment operator

outFile << "whatever" << endl;

I tried doing this as a Macro function as well:

#define OUTPUT outFileRequested?outFile:cout

OUTPUT << "whatever" << endl;

But that gave me a compiler error as well.

I supposed I could either use an IF-THEN block for every output, but I'd like to avoid that if I could. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

吃颗糖壮壮胆 2024-07-17 18:06:49

使用参考。 请注意,引用的类型必须是 std::ostream,而不是 std::ofstream,因为 std::cout 是一个 std::ostream,因此您必须使用最小公分母。

std::ofstream realOutFile;

if(outFileRequested)
    realOutFile.open("foo.txt", std::ios::out);

std::ostream & outFile = (outFileRequested ? realOutFile : std::cout);

Use a reference. Note that the reference must be of type std::ostream, not std::ofstream, since std::cout is an std::ostream, so you must use the least common denominator.

std::ofstream realOutFile;

if(outFileRequested)
    realOutFile.open("foo.txt", std::ios::out);

std::ostream & outFile = (outFileRequested ? realOutFile : std::cout);
⒈起吃苦の倖褔 2024-07-17 18:06:49

我假设你的程序的行为类似于标准的unix工具,当没有给定一个文件时,它将写入标准输出,当给定一个文件时,它将写入该文件。 您可以重定向cout以写入另一个流缓冲区。 只要您的重定向有效,写入 cout 的所有内容都会透明地写入您指定的目的地。 一旦重定向对象超出范围,原始流就会被放入,输出将再次写入屏幕:

struct CoutRedirect { 
    std::streambuf * old; 
    CoutRedirect():old(0) {
        // empty
    }

    ~CoutRedirect() {
        if(old != 0) {
            std::cout.rdbuf(old);
        }
    }

    void redirect(std::streambuf * to) {
        old = std::cout.rdbuf(to);
    }
}

int main() {
    std::filebuf file;
    CoutRedirect pipe;
    if(outFileRequested) {
        file.open("foo.txt", std::ios_base::out);
        pipe.redirect(&file);
    }
}

现在,只要管道在 main 中处于活动状态,cout 就会重定向到文件。 您可以通过使其不可复制来使其更加“生产就绪”,因为它还没有准备好被复制:如果副本超出范围,它将已经恢复原始流。

I assume your program behaves like standard unix tools, that when not given a file will write to standard output, and when given a file will write into that file. You can redirect cout to write into another stream buffer. As long as your redirection is alive, everything written to cout is transparently written to the destination you designated. Once the redirection object goes out of scope, the original stream is put and output will write to the screen again:

struct CoutRedirect { 
    std::streambuf * old; 
    CoutRedirect():old(0) {
        // empty
    }

    ~CoutRedirect() {
        if(old != 0) {
            std::cout.rdbuf(old);
        }
    }

    void redirect(std::streambuf * to) {
        old = std::cout.rdbuf(to);
    }
}

int main() {
    std::filebuf file;
    CoutRedirect pipe;
    if(outFileRequested) {
        file.open("foo.txt", std::ios_base::out);
        pipe.redirect(&file);
    }
}

Now, cout is redirected to the file as long as the pipe is alive in main. You can make it more "production ready" by making it non-copyable, because it's not ready to be copied: If the copy goes out of scope, it would restore the original stream already.

坚持沉默 2024-07-17 18:06:49

您可以在这里找到有关如何执行此操作的非常详细的说明:
http://groups.google.com/group/ comp.lang.c++/msg/1d941c0f26ea0d81?pli=1

希望有人能更清楚地写出这一点,以便堆栈溢出能够得分......

You can find a very detailed explanation of how to do this here:
http://groups.google.com/group/comp.lang.c++/msg/1d941c0f26ea0d81?pli=1

Hopefully someone will write this up more clearly for stack overflow to take the points...

你是暖光i 2024-07-17 18:06:49

遵循 Adam Rosenfield 的轨迹,但修复了使用三元和逗号运算符的引用初始化问题:(

bool outFileRequested = false;

std::ofstream realOutFile;
std::ostream & outFile = outFileRequested
    ? realOutFile.open("foo.txt", std::ios::out), realOutFile
    : std::cout;

outFile << "some witty remark";

在 VS 中测试)

Following Adam Rosenfield's tracks, but fixing the reference initialization problem with ternary and comma operators:

bool outFileRequested = false;

std::ofstream realOutFile;
std::ostream & outFile = outFileRequested
    ? realOutFile.open("foo.txt", std::ios::out), realOutFile
    : std::cout;

outFile << "some witty remark";

(Tested in VS)

烏雲後面有陽光 2024-07-17 18:06:49

我认为 Adam 走在正确的轨道上,但我不认为你可以分配引用 - 你需要使用指针:然后

std::ofstream realOutFile;
std::ostream * poutFile;

if(outFileRequested)
{
    realOutFile.open("foo.txt", std::ios::out);
    poutFile = &realOutFile;
}
else
    poutFile = &std::cout;

你可以将引用定义为指针的值,但它不会是全局的

std::ostream & outFile = *poutFile;

I think Adam's on the right track but I don't think you can assign references - you need to use a pointer instead:

std::ofstream realOutFile;
std::ostream * poutFile;

if(outFileRequested)
{
    realOutFile.open("foo.txt", std::ios::out);
    poutFile = &realOutFile;
}
else
    poutFile = &std::cout;

you could then define a reference to be the value of the pointer, but it wouldn't be global

std::ostream & outFile = *poutFile;
怪我太投入 2024-07-17 18:06:49

我不确定您是否可以将 cout 分配给 ofstream 类型的变量。 cout 是 ostream 类型的对象(而 cin 是 istream 类型),我不确定其中一个是从另一个继承的。 因此,也许检查文件是否已给定/存在并创建适当的流类型将是更好的方法。

I'm not sure that you can assign cout to a variable of type ofstream. cout is an object of type ostream (whereas cin is of type istream) and I'm not sure that one inherits from the other. So, maybe something checking to see if a file was given/exists and creating the appropriate stream type would be a better approach.

鸠书 2024-07-17 18:06:49

这花了大约两个小时才得到。 基本上,我有一个运行测试套件的外部类。 我发送委托来运行测试,因此为了访问输出,我需要发送输出流。 我想我可以为每个测试做不同的流。 无论如何,我想传入ofstream以供稍后使用。

// Main code to create Test Suite Object
ofstream debugFile("debug.txt");
TestSuiteObject* myTestSuite = new TestSuiteObject(&debugFile);

// Test Suite Object
class TestSuiteObject: public Test::Suite
{
public:
 TestSuiteObject(std::ofstream* debug) : m_debug(*debug)
 {
  m_debug << "some witty remark" << std::endl;
  TEST_ADD(TestSuiteObject::test1);
  TEST_ADD(TestSuiteObject::test2);
  TEST_ADD(TestSuiteObject::test3);

 }

 void test1();
 void test2();
 void test3();

private:
 std::ofstream& m_debug;
};

This took about two hours to get. Basically, I have a external class running a test suite. I send in a delegate to run the tests, so in order to have access to output I need to send in an output stream. I guess I could have done a different stream per test. Anyways, I wanted to pass in the ofstream to be used later.

// Main code to create Test Suite Object
ofstream debugFile("debug.txt");
TestSuiteObject* myTestSuite = new TestSuiteObject(&debugFile);

// Test Suite Object
class TestSuiteObject: public Test::Suite
{
public:
 TestSuiteObject(std::ofstream* debug) : m_debug(*debug)
 {
  m_debug << "some witty remark" << std::endl;
  TEST_ADD(TestSuiteObject::test1);
  TEST_ADD(TestSuiteObject::test2);
  TEST_ADD(TestSuiteObject::test3);

 }

 void test1();
 void test2();
 void test3();

private:
 std::ofstream& m_debug;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文