【问题标题】:Using standard io stream:stdin and stdout in a matlab exe在 matlab exe 中使用标准 io 流:stdin 和 stdout
【发布时间】:2013-05-22 11:26:27
【问题描述】:

问题

我希望它在运行(已编译)的 Matlab 可执行文件中“监听”标准输入流。

我认为这是用c 或类似语言完成的:

#include stdio.h
fgets(line, 256, stdin)

或者更详细地说,它可以这样使用:

if (!fgets(line, 256, stdin))
    return;
if (line[0] == '\n')
    continue;
sscanf(line, "%s", command);

回答

为了完整起见,我将保持背景和注释不变,但在 Amro 和 EitanT 的帮助下,我设法解决了问题。

背景

我找到了其他语言的方法,here 是编译过程的一些说明。

但是,我在任何地方都没有找到如何“收听”Matlab 中的输入。 我最接近的是 Octave 中类似 C 的 IO 的 this description,但是当我在 MATLAB 中寻找解决方案时,我无法在这方面取得进展。

请注意,更改或包装通过流发送数据的程序是不可能的,我更喜欢纯 MATLAB 解决方案,而不是包装我的整个程序。如果我用不同的语言从 MATLAB 中调用一个简单的函数,那就没问题了。

我尝试了什么?

我尝试了命令窗口中的一些函数,例如 fgets(0)fid = 0 似乎是对应于 stdin 的 id(如 @EitanT 所述,并在尝试 fopen(0) 时看到) ) ) 但它只是返回:

Operation is not implemented for requested file identifier.

我也考虑过使用 MATLAB 中的选项来调用系统命令或执行 java / perl 命令,但到目前为止没有运气。我也不确定这些在编译后是否仍然有效。

此外,我尝试使用input('prompt','s'),这在我通过cmd 打开程序时有效,但在我按Enter 之前什么都不做。 (这当然是我听的程序永远不会做的,在最好的情况下我可以在每一行的末尾得到\n)。

我也尝试过 waitinput from File Exchange,但我认为这是一个死胡同,因为它没有捕获任何东西,而且似乎表现很差。

备注

  1. 我使用的是 Windows 7 和 MATLAB 2012b。
  2. 我找到了popenon File Exchange,但这似乎不适用于 Windows。
  3. 当我简单地键入 'show me' 之类的内容时,它会正确发送到标准输出流。

【问题讨论】:

  • 您为什么不直接使用 MATLAB Compiler 创建共享库而不是独立应用程序。这样,您就可以构建自己的 C/C++ 程序,该程序像往常一样与标准输入/输出交互并链接到生成的 MATLAB 库。顺便说一句,您链接到的 pdf 文档非常过时。这是最新的:mathworks.com/help/pdf_doc/compiler/compiler.pdf
  • 我必须说不清楚你的问题是什么。所以让我弄清楚;您正在尝试使用已编译的 MATLAB 应用程序中的 input 函数,但它不起作用。是这样吗?
  • @DennisJaheruddin 不如编写一个 MEX 程序,而不是使用 MATLAB 的内置 input() 需要点击“enter”键来提交输入?
  • @EitanT 显然缺乏回车并不是问题的根源。我已经提出了一个答案,但当然仍然欢迎 cmets。感谢您的帮助!

标签: windows matlab stdout stdin matlab-compiler


【解决方案1】:

让我用一个玩具例子来说明。考虑以下 MATLAB 函数:

问候.m

function greet()
    str = input('Enter your name: ','s');
    fprintf('Hello %s\n',str)
end

现在让我们将它编译成一个独立的应用程序。请注意,如果您使用deploytool 工具,请确保选择“控制台应用程序”而不是“Windows 独立应用程序”作为目标。后者显然会生成一个可执行文件,其中标准输入连接到系统 shell 而不是 MATLAB 命令提示符..

如果您更喜欢自己直接编译,请使用以下调用:

mcc -o hello -W main:hello -T link:exe -N -v greet.m

(作为参考,“Windows 应用”目标发出 -W WinMain:hello 代替)

运行可执行文件会产生:

C:\> hello
Enter your name: Amro
Hello Amro

正确处理来自键盘的输入。

【讨论】:

  • 我认为input 等待'\n'...也许我错了,但我认为这不是丹尼斯正在寻找的功能。
  • 我同意这个问题并不清楚丹尼斯在寻找什么,但我的意思是使用“控制台应用程序”而不是“Windows 应用程序”。例如,您也可以尝试:echo Amro | hello,它也可以工作。也就是说输入流已正确连接到应用程序(无论您是从键盘以交互方式获取它还是通过管道将内容输入其中)。因此,您可以使用任何其他功能从标准输入读取
  • 事实上,我确实选择了一个 Windows 独立应用程序,因此希望它能解决大部分问题。有机会我会试试的。当我使用cmd 打开程序时,我遇到的情况是,如果我输入123 作为对input 请求的响应,然后按回车键,它就可以工作。但是,如果我不按 Enter,则不会发生任何事情。虽然我不确定,但我怀疑问题在于其他程序没有按回车。
  • @DennisJaheruddin:正如我在上面的 cmets 中所说,按照我的看法,您应该真正构建“C/C++ 共享库”而不是独立应用程序。这样您就可以编写自己的主程序来驱动程序的流程。..
  • 谢谢,您的示例(但不明白我的问题是什么)让我意识到从cmd 接收输入实际上与通过标准输入流接收内容是一回事。控制台应用程序的构建肯定会给程序一种更自然的感觉(因为它现在实际上会在您双击它时打开cmd),但我仍然会检查独立应用程序是否也可以做到这一点。如果是这样,那么我想我不能接受这个答案,但无论如何我很高兴给你赏金,因为你肯定让我解决了这个问题。
【解决方案2】:

原来input读取的是标准输入流。

我无法收集输入的原因是因为我使用它如下:

input('prompt','s')

因此,字符串 'prompt' 被发送到调用我的应用程序的程序,并且由于它认为这是一个无效的响应/请求,它没有发送任何内容。

我已经成功地制作了一个小型测试程序,并且不像我之前怀疑的那样,其他应用程序在发送命令后没有按回车不是问题。

一般解决方案

这是我目前的设置方式,

while 1
   stdin = input('','s'); % Note the empty first argument
   if ~isempty(stdin)
    stdout = process_input(stdin);
    stdout % Displaying the result (And thus sending it to stdout)
   end
end

【讨论】:

  • 我收到一个带有空提示字符串的警告。 “警告:由于 mxarraytostring 失败,未显示输入提示”。知道如何解决它(除了放置一个非空字符串)?
  • 问题是Matlab编译器想要创建一个指向字符串的指针,而这个指针并没有真正创建。我可以用input(char(0),'s'); 来规避这种变暖。 (一些信息compgroups.net/comp.soft-sys.matlab/string-ascii-null/806917
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-19
  • 1970-01-01
  • 2011-01-24
  • 2019-03-30
  • 2020-04-07
相关资源
最近更新 更多