ゲームに必要なファイルのリストを出力するユーティリティがあります。そのユーティリティを C プログラム内で実行し、その出力を取得して、同じプログラム内で操作できるようにするにはどうすればよいですか?
更新: 情報が不足しているため、良い判断です。このユーティリティは一連の文字列を吐き出し、これは Mac/Windows/Linux 間で移植可能であると想定されています。ユーティリティを実行し、その出力を保持するプログラムによる方法を探していることに注意してください(標準出力に出力されます)。
ゲームに必要なファイルのリストを出力するユーティリティがあります。そのユーティリティを C プログラム内で実行し、その出力を取得して、同じプログラム内で操作できるようにするにはどうすればよいですか?
更新: 情報が不足しているため、良い判断です。このユーティリティは一連の文字列を吐き出し、これは Mac/Windows/Linux 間で移植可能であると想定されています。ユーティリティを実行し、その出力を保持するプログラムによる方法を探していることに注意してください(標準出力に出力されます)。
他の人が指摘したようにpopen()
、最も標準的な方法です。そして、この方法を使用した例を提供する回答がなかったため、次のようになります。
#include <stdio.h>
#define BUFSIZE 128
int parse_output(void) {
char *cmd = "ls -l";
char buf[BUFSIZE];
FILE *fp;
if ((fp = popen(cmd, "r")) == NULL) {
printf("Error opening pipe!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
printf("OUTPUT: %s", buf);
}
if (pclose(fp)) {
printf("Command not found or exited with error status\n");
return -1;
}
return 0;
}
出力例:
OUTPUT: total 16
OUTPUT: -rwxr-xr-x 1 14077 14077 8832 Oct 19 04:32 a.out
OUTPUT: -rw-r--r-- 1 14077 14077 1549 Oct 19 04:32 main.c
Unix っぽい環境での単純な問題については、 を試してくださいpopen()
。
マニュアルページから:
popen() 関数は、パイプを作成し、フォークしてシェルを呼び出すことにより、プロセスを開きます。
読み取りモードを使用する場合、これはまさにあなたが求めていたものです。Windowsに実装されているかどうかはわかりません。
より複雑な問題については、プロセス間通信を調べる必要があります。
popen は Windows でサポートされています。こちらを参照してください。
http://msdn.microsoft.com/en-us/library/96ayss4b.aspx
クロスプラットフォームにしたい場合は、popen が最適です。
Windows 環境でコマンド ラインを使用していると仮定すると、パイプまたはコマンド ライン リダイレクトを使用できます。例えば、
commandThatOutputs.exe > someFileToStoreResults.txt
また
commandThatOutputs.exe | yourProgramToProcessInput.exe
プログラム内で、C 標準入力関数を使用して他のプログラム出力 (scanf など) を読み取ることができます: http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output .asp . ファイルの例を使用して、fscanf を使用することもできます。これは Unix/Linux でも動作するはずです。
これは非常に一般的な質問です。出力の種類 (テキストのみか、バイナリ ファイルか) や処理方法などの詳細を含めることができます。
編集:万歳の明確化!
STDOUT のリダイレクトは面倒なようで、.NET でリダイレクトする必要があり、あらゆる種類の頭痛の種になりました。適切な C の方法は、子プロセスを生成し、ファイル ポインターを取得することであるように見えますが、突然頭が痛くなります。
そこで、一時ファイルを使用するハックを紹介します。シンプルですが、うまくいくはずです。これは、速度が問題にならない (ディスクへのヒットが遅い) 場合、または使い捨ての場合にうまく機能します。エンタープライズ プログラムを構築している場合は、他の人が推奨する方法を使用して、STDOUT リダイレクトを調べるのがおそらく最善です。
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE * fptr; // file holder
char c; // char buffer
system("dir >> temp.txt"); // call dir and put it's contents in a temp using redirects.
fptr = fopen("temp.txt", "r"); // open said file for reading.
// oh, and check for fptr being NULL.
while(1){
c = fgetc(fptr);
if(c!= EOF)
printf("%c", c); // do what you need to.
else
break; // exit when you hit the end of the file.
}
fclose(fptr); // don't call this is fptr is NULL.
remove("temp.txt"); // clean up
getchar(); // stop so I can see if it worked.
}
ファイルのアクセス許可を確認してください。現在、これはファイルを exe と同じディレクトリにスローするだけです。nix /tmp
、C:\Users\username\Local Settings\Temp
Vista、またはC:\Documents and Settings\username\Local Settings\Temp in 2K/XP
. /tmp
OSXで動作すると思いますが、使ったことはありません。
Linux と OS X では、popen()
dmckee が指摘したように、両方の OS がその呼び出しをサポートしているため、本当に最善の策です。Windows では、これが役立ちます: http://msdn.microsoft.com/en-us/library/ms682499.aspx
MSDN のドキュメントには、Windows プログラムで使用すると、_popen 関数が無効なファイル ポインターを返すため、プログラムが無期限に応答を停止すると書かれています。_popen は、コンソール アプリケーションで適切に機能します。入力と出力をリダイレクトする Windows アプリケーションを作成するには、Windows SDK の「リダイレクトされた入力と出力を持つ子プロセスの作成」を参照してください。
次のように使用できますsystem()
。
system("ls song > song.txt");
ここls
で、 はフォルダ song の内容を一覧表示するコマンド名song
で、現在のディレクトリ内のフォルダです。結果のファイルsong.txt
は現在のディレクトリに作成されます。