こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

コマンドを実行してコマンドライン文字列を読み込む

C言語(他の言語でも)で、コマンドを実行して結果の文字列を取得できるような関数はないでしょうか?

コマンドを実行したプログラム内の変数に文字列として保持して、処理したいと考えています。

Windowsです。

よろしくお願い致します。

投稿日時 - 2007-08-26 14:51:11

QNo.3287937

yzn

すぐに回答ほしいです

質問者が選んだベストアンサー

外部コマンド実行のしっかりしたサポートがある言語を選ぶのがいいと思いますが、Cプログラム中から外部コマンドを呼び出したいというなら。。。
できるだけ、C言語から逸脱せずにやろうとすると、コマンド実行は system() 関数で実行できて、かつ、"> filename" をつけてコマンド結果をファイルにリダイレクトできることを仮定すれば、以下のような感じになりますかね。


あと、エラー処理などいっさいしていないことや、文字数の数え方を端折っていますので、適当に修正してください。
コマンド実行結果の格納に何文字いるかは、きっちりやろうと思えば、一度、fseek() などしないで、
・ファイルを実際読み込んでカウントし、rewind() するか、
・ファイルを読み込みながら、文字を格納している領域を拡張する
ということをします。ここでは、ファイルサイズよりは大きくならないだろう(たとえば、改行文字の変更などにより小さくはなっても大きくならない)と仮定してファイル位置から文字数を推定しています。

=====
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *execute(const char *cmd)
{
static char *cmdbuf = NULL;
static size_t bufsiz = 0;
static char fn[L_tmpnam];
const char *redirect = " > ";
size_t siz;

tmpnam(fn);
if ((siz = strlen(cmd) + strlen(redirect) + strlen(fn) + 1) > bufsiz)
cmdbuf = realloc(cmdbuf, bufsiz = siz);
strcpy(cmdbuf, cmd);
strcat(cmdbuf, redirect);
strcat(cmdbuf, fn);
system(cmdbuf);
return fn;
}

char *result(const char *fn)
{
long fsiz;
char *rv, *p, c;
FILE *fp = fopen(fn, "r");

fseek(fp, 0, SEEK_END);
fsiz = ftell(fp);
rv = p = malloc(fsiz + 1);
rewind(fp);
while ((c = getc(fp)) != EOF) *p++ = c;
*p = '\0';
fclose(fp);
remove(fn);

return rv;
}

int main(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; ++i) {
char *str = result(execute(argv[i]));
printf("%s\n", str);
free(str);
}
}
===
Usage: program command1 command2 ...

投稿日時 - 2007-08-26 15:52:21

ANo.3

このQ&Aは役に立ちましたか?

3人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

もうひとつ訂正: main()の最後に
  return 0;
をつけておいてください(C++ を書くほうが多いせいで、常に 0 を返す場合は、つい省略してしまう^^;)。

プログラム内で、エラーチェックを全然してないので、ほんとにエラーが起きていないかどうかはわかりませんが(笑)

投稿日時 - 2007-08-26 21:52:24

お礼

丁寧に教えていただき、ありがとうございました。
参考にさせていただき、なんとか期待通り動くようになりました。
やはり、VBSとかケースバイケースで便利なものを使い分けられるように覚えなければいけませんね・・・
勉強します!

投稿日時 - 2007-08-30 00:35:36

ANo.4

訂正:result() という関数内の
  char *rv, *p, c;

  char *rv, *p;
  int c;
に修正しておいてください。たぶん、そのままでも動作すると思いますが、char が符号無しだったらまずいかも^^ 失礼しました。

投稿日時 - 2007-08-26 21:01:31

ANo.2

その実行結果は標準出力に出てくるのでしょうか?
もしそうで、かつ「どんな言語」でも。というのなら
$result = `command`;
とかできちゃうPerlとかRubyがありますが。

C/C++ということなら、実行するコマンドと双方向でやりとりするのでなければ
popen が使えます。
Win32API でごりごりやるとか、Unixみたいに無名パイプをpipe()でつくって
とかでもいいですけど。

投稿日時 - 2007-08-26 15:28:24

ANo.1

★アドバイス
・コマンドラインで実行した結果をファイルに保存。→リダイレクション機能。
 その後プログラムから保存された実行結果のファイル内容を読み込めば利用は出来ます。
>C言語(他の言語でも)で、コマンドを実行して結果の文字列を取得できるような関数はないでしょうか?
 ↑
 fopen、fgets、fclose 関連を使って下さい。
・以上。

投稿日時 - 2007-08-26 15:14:26

あなたにオススメの質問