如何让MATLAB的system()或dos()实时显示控制台输出?

时间:2016-07-13 21:34:40

标签: c++ matlab console

我有一个MATLAB脚本,使用system()命令调用可执行文件(用C ++编写),如下所示:

exe_status = system('MySimulation.exe', arguments);

由于可执行文件可能需要很长时间才能运行(最多几个小时),因此我在其中包含一个估计剩余时间并将其输出到控制台的函数。如果我在MATLAB之外运行可执行文件,Windows控制台看起来大致如下:

Simulation #B01 initiated...
Completion: 0.57%    Time remaining: 183 m 2 s

使用\r字符,“完成”行每秒重写一次。这非常有效,让我知道何时回来分析数据。

不幸的是,从MATLAB控制台调用可执行文件的效果不同。在完全显示任何控制台输出之前,MATLAB一直等到可执行文件终止,这使我的计时器无法实现。

我尝试过以下命令,但它们都有相同的行为:

exe_status = system('MySimulation.exe', arguments);
exe_status = system('MySimulation.exe', arguments, '-echo');
exe_status = dos('MySimulation.exe', arguments);
exe_status = dos('MySimulation.exe', arguments, '-echo');

除非我读错了,似乎MATLAB documentation表明'-echo'可用于在可执行文件仍在运行时回显命令输出,但它对我的特定程序没有影响

2 个答案:

答案 0 :(得分:1)

我很好奇所以我尝试了一些东西。我尝试了一个bash脚本,一个c可执行文件和一个python脚本,所有这些脚本都在“实时”中显示其输出Matlab命令窗口,这是问题的理想行为。我无法重新创造问题中描述的情况。

所以我怀疑:

a)无论你用什么方法套印同一条线都是问题所在。它可能不是\r的使用,它可能与您在C ++可执行文件中使用的特定打印方法有关。我会尝试不使用叠印,只需使用您能想到的最简单的打印声明在新行上打印状态。

,或者

b)问题是特定于操作系统的。

为了完整性,以下是我尝试的内容和结果(环境和打印声明)的详细信息:

  1. bash脚本; echo ""
  2. 编译c代码; printf("\n")
  3. python 2.7脚本; print("".format() )
  4. os内置 ping 程序(如评论中所述)
  5. 我在Matlab中使用system命令运行此操作,例如system('./timer_out');。在所有情况下:

    - 如果没有第二个输出变量,打印输出“实时”出现,无论使用'-echo'标志还是尾随分号,例如:

    tic; system('./timer_out'); toc
    

    - 如果给出输出变量,则打印输出被抑制,例如:

    tic; [s,r]=system('./timer_out'); toc
    

    - 如果输出变量并且使用了'-echo'标志,则实时出现打印输出,例如:

    tic; [s,r]=system('./timer_out','-echo'); toc
    

    此行为符合文档。这些测试在OS X上使用了Matlab R2015b。

答案 1 :(得分:1)

我想我原来的问题措辞过于粗略 - 我通过修改C ++代码而不是MATLAB代码找到了解决方案。具体来说,我在控制台打印命令的末尾添加了std::endlstd::flush,如下所示:

std::cout << "Simulation #B01 initiated..." << std::endl;

我的猜测是,刷新流会提示MATLAB“实时”(或多或少)向控制台显示流的内容,这是Windows控制台在我的特定计算机上使用我的特定操作系统不需要的东西我相信这里有一个关于可移植性的人生课程,但我对我正在做的事情已经足够了解了。

作为旁注,我注意到MATLAB does not properly recognize the carriage return character \r in the console。为了防止我的可执行文件通过潜在的数千行更新状态向控制台发送垃圾邮件,我已经替换了旧的更新行功能

void time_remaining( ... ) {

    std::string completion_update = ( ... );

    std::cout << completion_update << "\r";

}

稍微复杂一点

int time_remaining( string_length, ... ) {

    for(i = 0; i < string_length; i++) std::cout << "\b";

    std::string completion_update = ( ... );

    std::cout << completion_update << std::flush;

    string_length = completion_update.length();

    return string_length;

}

依赖于退格字符\b和字符串completion_update的上一次迭代的字符长度。