如果这个问题命名错误,我道歉,但让我通过一个简单的类比来解释Java.请注意,这个问题是关于Matlab,而不是Java.
在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");
Run Code Online (Sandbox Code Playgroud)
在Matlab中,写入标准输出的一种标准方法是编写表达式,变量或语句而不使用后面的分号.我将如何重写我的Matlab语句以将此(ascii)输出转换为文件?
我想避免重定向stdout到文件的解决方案,因为我仍然希望在控制台上打印一些东西.
另外,我不想指定要写入文件的对象的类型,因为标准方式不需要类型规范.
更新:特别是,据我所知,printf函数族需要类型规范(不同的格式字符串取决于对象的类型).我试图避免这种情况,因为我寻求更通用的解决方案.
你想要做的是找到一个通用的字符串转换display(),用它来构建你的输出作为字符串,然后你可以将它传递给fprintf()或其他正常的输出函数.
通过省略分号产生的Matlab输出是通过调用display()表达式的结果来完成的.Matlab display为所有内置类型提供了实现,并为用户提供的对象提供了回退实现.该disp()函数以相同的方式显示值,但省略变量名称.
这基本上相当于Java的toString函数,当你将任意对象打印到a时,它会在幕后被调用PrintStream.显示功能PrintStream本身并不是本身,而是在toString知道如何将对象转换为显示字符串的多态方法中.不同之处在于Java toString返回一个String数据值,它易于以编程方式工作并与其他操作组合,因此您可以操作它将其发送到您想要的位置,但是Matlab display并且disp总是输出到stdout而不是给你一个字符串.
你想要的东西可能会让你的display输出作为字符串,然后你可以输出你想要的,使用fprintf()或其他字符串输出函数.
一种简单的方法是用来evalc()调用display和捕获输出.该evalc函数允许您运行任意Matlab代码,并捕获将转移stdout到char变量的输出.您可以创建通用转换函数并将其应用于您想要的任何值.
function out = tostr(x)
out = evalc('disp(x)');
end
Run Code Online (Sandbox Code Playgroud)
另一个选择是定义一个新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
Run Code Online (Sandbox Code Playgroud)
Matlab没有自动调用显示转换的格式化输出函数,所以你必须在很多情况下明确地调用转换,所以它会比Java更加冗长.(除非你想全力以赴地编写自己的多态自动转换输出函数或字符串包装器对象.)如果你想使用占位符,通过强制转换所有的args很容易.
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
Run Code Online (Sandbox Code Playgroud)
如果你想得到想象,你可以printf通过printf自己解析格式参数来进行混合转换,定义一个新的占位符,就像%y调用你tostr()的参数然后打印那个字符串(可能是用占位符替换%s和带有tostr()结果的参数),并printf使用未转换的参数传递所有正常占位符.但是这很难实现,并且计算成本很高.
您可以通过提供char将对象值转换为显示字符串的转换来使其行为更像Java ,但这与Matlab现有数字char转换的工作方式不一致,因此它不会完全通用,并且您会遇到一些奇怪的边缘情况所以我不建议这样做.你可以通过定义一个@string包装char字符串的新类来做一个更安全的形式,但是通过调用你的tostr()而不是来进行隐式转换char().但这可能是一个很大的性能影响,因为Matlab OOP对象比使用内置类型和普通函数的操作慢得多.
对于背景:基本上,你需要fprintf在Matlab中传递显式转换的原因,但是你不需要使用PrintStreamJava中的东西fprintf是继承自C的,它没有运行时类型检测,尤其是varargs,语言.Matlab确实如此,因此fprintf比它需要的更有限.但是,fprintf给你的是对数值格式和简洁调用形式的细粒度控制.这些都是有用的,正如Java程序员多年来一直抱怨他们没有使用Java并最终添加它们一样.只是Matlab坚持使用C支持的fprintf转换,他们可以轻松添加一些新的通用转换,在运行时检查输入的类型,并为您提供所需的通用输出支持.
| 归档时间: |
|
| 查看次数: |
650 次 |
| 最近记录: |