3

この質問の名前が不適切な場合は申し訳ありませんが、Java との単純な類似性から説明させてください。この質問は Java ではなく、Matlab に関するものです。

Java では、stdoutストリームに書き込む標準的な方法はSystem.out.println. この正確な出力をファイルに出力したい場合は、PrintStreamobjectを作成し、それをファイルに向けて、 への呼び出しmyPrinterを への呼び出しに置き換えることができます。System.out.printlnmyPrinter.println

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

Matlab では、標準出力に書き込む標準的な方法の 1 つは、セミコロンを付けずに式、変数、またはステートメントを記述することです。この (ascii) 出力を代わりにファイルに取得するには、Matlab ステートメントをどのように書き直しますか?

ファイルにリダイレクトstdoutするソリューションは避けたいと思います。コンソールに何かを出力したいからです。

さらに、標準的な方法では型指定が必要ないため、ファイルに書き込まれるオブジェクトの型を指定する必要はありません。

更新: 特に、私の知る限り、printf関数のファミリには型指定が必要です (オブジェクトの型に応じて異なる書式文字列)。より一般的な解決策を求めているため、これを回避しようとしています。

4

1 に答える 1

7

あなたがしたいのは、のような一般的な文字列変換を見つけ、display()それを使用して出力を文字列として構築し、それをfprintf()または他の通常の出力関数に渡すことができます。

セミコロンを省略することによって生成される Matlab 出力display()は、式の結果を呼び出すことによって行われます。Matlab は、displayすべての組み込み型の実装と、ユーザー提供のオブジェクトのフォールバック実装を提供します。関数はdisp()同じ方法で値を表示しますが、変数名を省略します。

toStringこれは基本的に、任意のオブジェクトを に出力するときに裏で呼び出されるJava の関数と同等ですPrintStream。表示機能はほとんどPrintStreamそれ自体ではなく、toStringオブジェクトを表示文字列に変換する方法を知っているポリモーフィック メソッドにあります。違いは、JavatoStringが String データ値を返すことです。これは、プログラムで簡単に操作したり、他の操作で構成したりできるため、操作して必要な場所に送信できますが、Matlabでは、文字列を返す代わりに常に stdout に出力しますdisplaydisp

あなたが望むのは、おそらくdisplay-style 出力を文字列として提供するものであり、fprintf()または別の文字列出力関数を使用して、必要な場所に出力できます。

簡単な方法の 1 つはevalc()、単に呼び出しdisplayて出力をキャプチャするために使用することです。このevalc関数を使用すると、任意の Matlab コードを実行し、代わりに変数に出力される出力をキャプチャできstdoutますchar。一般的な変換関数を作成して、必要な値に適用できます。

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

もう 1 つのオプションは、新しいdispstr()関数を定義し、それを記述して Matlab の組み込み型を変換し (おそらくevalc手法を使用して)、記述したオブジェクトでオーバーライドdispstrして、多態的に呼び出すことです。evalc作業は増えますが、遅くて壊れやすいため、最終的にはよりクリーンで高速になる可能性があります。またmat2str、別の出力メカニズムに関するアイデアについては、 を参照してください。

次に、このような呼び出しを使用して、型を指定せずに一般的に値を出力できます。%s2 番目の形式では、オブジェクトの種類に関係なく、すべてのプレースホルダーが使用されることに注意してください。

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解析し、そのような新しいプレースホルダーを定義して、引数であなたを呼び出し、その文字列を出力することで、混合変換を行うことができます (おそらく、プレースホルダーを に置き換え、引数を結果に置き換えることによって)。変換されていない引数とともに、すべての通常のプレースホルダーを渡します。ただし、これは実装が難しく、計算コストが高くなる可能性があります。printf%ytostr()%stostr()printf

オブジェクト値を表示文字列に変換する変換を提供することで、よりJavaのように動作させることができますが、それcharはMatlabの既存の数値からchar変換への変換方法と矛盾するため、完全に一般的ではなく、いくつかの奇妙なエッジケースに遭遇します.ので、お勧めしません。@string文字列をラップする新しいクラスを定義することで、より安全な形式を実現できますが、代わりにcharyour を呼び出して暗黙的な変換を行います。ただし、Matlab OOP オブジェクトは組み込み型や単純な関数を使用した操作よりも大幅に遅いため、これはパフォーマンスに大きな影響を与える可能性があります。tostr()char()

背景について: 基本的に、fprintfMatlab で明示的な変換を渡す必要PrintStreamがあるが、Java のものを渡す必要がない理由fprintfは、C から継承されているためです。C には、特に可変引数の実行時の型検出がありませんでした。言語。Matlab はそうであるため、fprintf必要以上に制限されています。しかし、何fprintf数値のフォーマットと簡潔な呼び出しフォームをきめ細かく制御できます。Java プログラマーが何年にもわたって Java にそれらがないと不満を漏らし、最終的にそれらを追加したことからも明らかなように、これらは便利です。Matlab が C でサポートされている fprintf 変換に固執しているだけで、実行時に入力の型を調べて、必要な汎用出力サポートを提供するいくつかの新しい汎用変換を簡単に追加できます。

于 2013-04-28T22:23:00.673 に答える