2013-04-28 66 views
3

我很抱歉,如果这个问题是错误的命名,但让我通过一个简单的Java类比来解释。 请注意,这个问题是关于Matlab,而不是Java。什么是Matlab的默认显示功能输出到文件而不是标准输出的等价物?

在Java中,写入stdout流的标准方式是System.out.println。 如果我们想要将这个确切的输出打印到一个文件中,我们可以创建一个PrintStream对象myPrinter,将它指向一个文件,并将调用替换为System.out.println,并调用myPrinter.println

System.out.println("Hello World"); 
PrintStream myPrinter = new PrintStream(new File("MyJournal.log")); 
myPrinter.println("Hello Log"); 

在Matlab中,一个标准的方式写入到标准输出是写一个表达式,变量或声明没有以下分号。 我将如何重写我的Matlab语句以将此(ascii)输出转换为文件?

我想避免将stdout重定向到文件的解决方案,因为我仍然希望将某些内容打印到控制台。

另外,我不希望有指定被写入到文件的对象的类型,因为标准的方法不需要类型规范。

更新:具体地讲,据我所知,printf函数系列需要类型规范(根据对象的类型不同的格式字符串)。我试图避免这种情况,因为我寻求更通用的解决方案。

+0

你的意思是像[fprintf](http://www.mathworks.nl/help/matlab/ref/fprintf.html)? – Kninnug 2013-04-28 19:46:43

+0

据我所知,'fprintf'需要一个指定打印对象的类型。 – merlin2011 2013-04-28 19:47:52

+0

用fopen()打开流,并用格式化数据的fprintf()或原始数据的fwrite()写入流。然后你用fclose()关闭你的流。 – 2013-04-28 19:48:39

回答

6

你想要做的是找到一个类似于display()的通用字符串转换,使用它将输出生成为字符串,然后将其传递给fprintf()或其他正常输出函数。

通过省略分号产生的Matlab的输出是通过在表达式的结果调用display()完成。 Matlab为所有内建类型提供了一个display实现,并为用户提供的对象提供了一个回退实现。 disp()函数以相同的方式显示值,但省略变量名称。

这基本上等同于Java的toString函数,当您将任意对象打印到PrintStream时,该函数在幕后调用。显示功能本身大多不在PrintStream本身,但在知道如何将对象转换为显示字符串的多态toString方法中。不同的是,Java的toString返回一个字符串数据值,这是很容易通过编程工作,并与其他业务组成,这样你就可以操纵它把它在那里你想要的,但Matlab的displaydisp总是输出到stdout,而不是给你一个弦回来。

你想要什么可能会给你display风格的输出作为一个字符串,然后你可以输出它在你想要的地方,使用fprintf()或另一个字符串输出函数。

一个简单的方法是使用evalc()只是调用display并捕获输出。该evalc功能可让您运行任意Matlab代码,并捕获会去stdoutchar变量,而不是输出。您可以创建一个通用转换函数并将其应用于您想要的任何值。

function out = tostr(x) 
    out = evalc('disp(x)'); 
end 

另一种选择是定义一个新的dispstr()功能,写Matlab的内置类型它转换(也许使用evalc技术),且覆盖你写的对象dispstr,和多态调用它。更多的工作,但它可能会变得更干净,更快,因为evalc是缓慢的,有时脆弱。另请参阅mat2str了解备用输出机制的想法。

然后,您将能够一般输出值,而不指定类型,使用这样的调用。请注意,在第二种形式中,无论对象的类型如何,占位符都是%s

function displaySomeArbitraryDataValues(fh, foo, bar, baz) 
% fh is a file handle previously opened with fopen() 
fprintf(fh, 'foo=%s, bar=%s and baz=%s', tostr(foo), tostr(baz), tostr(qux)) 
end 

Matlab的不具有自动调用显示转换的格式输出功能,所以你必须显式调用转换在很多情况下,因此这将是一个多一点的Java罗嗦。 (除非你想全力以赴编写自己的多态自动转换输出函数或字符串包装对象。)如果你想使用占位符,通过强制转换所有的参数很容易。

function out = sprintf2(format, varargin) 
%SPRINTF2 A sprintf equivalent with polymorphic input conversion 
% Use '%s' placeholders for everything in format, regardless of arg type 
args = varargin; 
strs = {} 
for i = 1:numel(args) 
    strs{i} = tostr(args{i}); 
end 
out = sprintf(format, strs{:}); 
end 

如果你想获得幻想,你也可以自己解析printf format参数,定义诸如%y一个新的占位符的参数调用你tostr()做混合printf转换,然后通过更换打印出字符串(可能%s的占位符和tostr()结果的参数),并将所有正常的占位符一起传递给printf,并带有未转换的参数。虽然这很难实现,并且可能在计算上很昂贵。

可以使其行为更加像Java提供char转换,这种转换转换对象值显示字符串,但是这与Matlab的现有数字到char转换是如何工作的不一致,所以它不会是完全通用的,和你会遇到一些奇怪的边缘情况,所以我不会推荐。通过定义一个包含char字符串的新类@string类,您可以通过调用tostr()而不是char()来实现隐式转换。不过,这可能会造成很大的性能下降,因为Matlab OOP对象比使用内置类型和普通函数的操作要慢得多。

有关背景:基本上,原因你需要显式转换传递给在Matlab fprintf,但你并不需要与PrintStream东西在Java是fprintf从C,它不具有运行时类型继承在语言中检测,尤其是可变参数。 Matlab的确如此,所以fprintf比它需要的更受限制。然而,fprintf确实给你的是对数值格式和简洁调用形式的细粒度控制。这些都是有用的,正如Java程序员多年来抱怨Java程序员没有使用Java并最终添加它们一样。这就是说,Matlab坚持支持C的fprintf转换,他们可以轻松地添加一些新的通用转换,在运行时检查输入的类型,并为您提供所需的通用输出支持。

相关问题