首页 > 解决方案 > 打印到文件和控制台 C++

问题描述

我正在尝试记录我的事件,所以我想使用 ostringstream 来保存输出,然后将其发送到我在屏幕上和文件 fstream fileOut 上打印输出的函数。它不起作用,它只是给我随机数,似乎不会在同一个文件上输出所有新输出,而是每次都创建一个新文件并删除之前的内容。我该怎么做呢?

打印发生的地方:

void Event::output(ostringstream* info) {
    std::cout << info << std::endl;
    fileOut << info << std::endl;
}

输出发生的地方:

ostringstream o;
if (time < SIM_TIME) {

    if (status->tryAssemble(train)) {
        Time ct;
        ct.fromMinutes(time);
        o << ct << " Train [" << train->getTrainNumber() << "] ";

        Time t(0, DELAY_TIME);
        o << "(ASSEMBLED) from " << train->getStart() << " " << train->getScheduledStartTime() <<
            " (" << train->getStartTime() << ") to " << train->getDest() << " " << train->getScheduledDestTime() <<
            " (" << train->getDestTime() << ") delay (" << train->getDelay() << ") speed=" << train->getScheduledSpeed() <<
            " km/h is now assembled, arriving at the plateform at " << train->getStartTime() - t << endl << endl;

        fileOut.open("testfile.txt", std::ios::out);
        if (!fileOut.is_open()) 
            exit(1);            //could not open file
            output(&o);
        train->setStatus(ASSEMBLED);
        time += ASSEMBLE_TIME;
        Event *event = new ReadyEvent(simulation, status, time, train);
        simulation->addEvent(event);

标签: c++fstreamostream

解决方案


它不起作用,它只是给我随机数

ostringstream您通过指针传递给您的函数。没有operator<<ostringstream*指针作为输入并打印其字符串内容。但是有一个operator<<将 avoid*作为输入并打印指针指向的内存地址。那就是您看到的“随机数”。任何类型的指针都可以分配给void*指针。

您需要取消引用ostringstream*指针才能访问实际ostringstream对象。即便如此,仍然没有operator<<将 aostringstream作为输入。但是,ostringstream有一个str()返回 a 的方法std::string,并且有一个operator<<用于打印 a 的方法std::string

void Event::output(ostringstream* info) {
    std::string s = info->str();
    std::cout << s << std::endl;
    fileOut << s << std::endl;
}

话虽如此,您应该通过ostringstreamconst 引用而不是通过指针传递,因为该函数不允许ostringstream传入 null ,并且它不会ostringstream以任何方式修改:

void Event::output(const ostringstream &info) {
    std::string s = info.str();
    std::cout << s << std::endl;
    fileOut << s << std::endl;
}

...

output(o);

似乎不会在同一个文件上输出所有新输出,而是每次都创建一个新文件并删除之前的内容。

那是因为您没有使用apporate标志打开文件1,所以它每次都会创建一个新文件,丢弃任何现有文件的内容。如果要改为附加到现有文件,则需要:

  • 使用ate标志“在打开后立即搜索到流的末尾”:

    fileOut.open("testfile.txt", std::ios::out | std::ios::ate);
    
  • 使用该app标志“在每次写入之前搜索到流的末尾”:

    fileOut.open("testfile.txt", std::ios::out | std::ios::app);
    

1:如果fileOut是 a std::ofstream,则不需要std::ios::out明确指定。


推荐阅读