• 締切済み

UNIX & Linux の標準出力で得たデータを、C言語のローカル変数に取り込むには?

c言語の関数を実行中に、UNIXにあるシェルコマンド"wc"の標準出力から得られるデータを、直接ローカル変数に入れたいと思います。 int hoge(void) { int ans; ans = system("wc"); return } こんな感じにしたかったのですが、systemコマンドでは、戻り値を期待できずに居ます。 何か善い方法はありませんか?

みんなの回答

回答No.4

標準入力にだしながら、標準出力の結果を受け取るというのは pipe(),fork()あたり使ったりして結構めんどくさいでしょうから、 どうしても、wcをコールしたいのなら、一旦、wcの標準入力にいれたいものをファイルに書いてから、popen ( "wc < ファイル" , "r"); すればいいのではないでしょうか。 ファイルの掃除とか、他のプロセスとファイルがぶつからないようにするとか考えないといけませんけど。

xcode_15
質問者

補足

ありがとうございます。 戴いた案は、私も考えましたが、同じようにファイルの後処理とかを複数回行わなければならず、処理がぶつかりそうなので断念しました。

回答No.3

オーバーヘッド考えたら、wc機能を行うCライブラリを使ったほうが速くないですか?

xcode_15
質問者

補足

ご回答、ありがとうございます。 >wc機能を行うCライブラリを使ったほうが速くないですか? それって、どの様なライブラリでしょうか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

まず「コマンドラインでは、'$ wc filename | program' とすればprogramの引数として値が渡りますが」と書かれていますが, これは wc filename の標準出力を program の標準入力に渡すということであって, 「引数として渡す」ということではありません. で本題ですが.... 「popenを使うと、書き込み用プロセスと読み込みようプロセスを立ち上げることになり、一見簡単そうで複雑なコードになりませんか?」というのは, ちょっと意味がわかりません. popen の仕様は確認しましたか? popen を使えば, プログラムの標準入出力をあたかもファイルであるかのように扱うことができます (もちろん普通のファイルと違って入出力を同時に実行することはできませんが). だから, 「ファイルから読み込む」のとほぼ同等の複雑さで「プログラムの標準出力を読み込む」ことができます.

xcode_15
質問者

補足

ご回答、ありがとうございます。 それって、こんな感じですよね。 #include <stdio.h> char *wc = "wc file"; main() { FILE *inpipe, *popen(); char buf[BUFSIZ]; inpipe = popen(wc, "r"); while (fgets(buf, sizeof buf, inpipe) != NULL) { buf[strlen(buf)-1] = ' '; fputs(buf, stdout); } printf("\n"); pclose( inpipe ); exit(0); }

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

それは「wc の返り値」をもらってるだけで, 「wc の出力」をもらっているわけではありません. UNIX&Linux 限定なら popen が簡単かな.

xcode_15
質問者

補足

ご回答、有難うございます。 popenを使うと、書き込み用プロセスと読み込みようプロセスを立ち上げることになり、一見簡単そうで複雑なコードになりませんか? 私がこのコマンド("wc")を使おうと思ったのは、既にあるコマンド(機能)でCのライブラリ関数の中に組み込めるのでは?と思ったからです。 コマンドラインでは、'$ wc filename | program' とすればprogramの引数として値が渡りますが、実行中のプログラムで、且つ、一つの関数(サブルーチン)の中で実現したいと思います。しかも、出来るだけシンプルに。

関連するQ&A

  • C言語のローカル変数の使い方について質問です。

    C言語の変数に関しての質問です。 グローバル変数を使わずに、関数内で宣言したローカルの変数を別のソースファイルで使用することって可能ですか? 例えば、a.cというソースファイルと、b.cというソースファイルがあります。 a.cの関数内で"FILE *fp;"と宣言したローカル変数を、b.cの関数内で共有して使うことはできるのでしょうか。 また、"fp"に直接アクセスはできなくても、間接的にアクセスできる方法があれば教えてください。 下に記述しているのは例え用に適当に書いたプログラムです。 --------------------- a.cのソースファイル --------------------- void Temp(void) { char file_name[128] = {}; errno_t error; FILE *fp; // ←この変数を別のソースで使いたいです scnaf_s("%s", file_name, 128); if(error = fopen_s(&fp, fname, "rb") != 0) { printf("ファイルがオープンできません"); return 0; } fclose(fp); } --------------------- b.cのソースファイル --------------------- void Temp2(void) { int size; // ここでa.cのTemp関数で宣言されている"fp"を使いたい fseek( fp, 0, SEEK_END ); fsize = ftell( fp ); fseek( fp, 0, SEEK_SET ); }

  • C言語の変数について

    C言語の変数について教えていただきたいです。 C言語で下記のような設定をした場合、変数A、Bに設定する値にはバイト数制限 はないのでしょうか? バイト数制限がなくなる場合、なぜそうなるのかを教えていただきたいです。 よろしくお願いします。 #include <stdio.h> void test( char **B); int main( int argc, char *argv[] ) { char *A = NULL; char *B = NULL; A = argv[1]; test( B ); return 0; } void test( char **B ) { strcpy(B, "ABCD"); return 0; }

  • teeコマンドを使わずにUNIXで標準出力とエラー出力を、ファイルと標準出力の両方に出すには?

    UNIX系のBシェルで、 コマンドを実行して、 その標準出力とエラー出力をログファイルに出力し、 かつ、同じものを標準出力にも出力したいのです。 また、その後でコマンドの戻り値$?をエラーチェックしたいです。 このため、パイプでteeコマンドを使用すると戻り値が上書きされてしまいます。 いったん一時ファイルに出力するしかないのでしょうか?

  • C#での変数スコープ?

    Net 2.0のC#で同一名の変数を使う場合について質問いたします。 以下のHoge1の場合には「 ローカルの変数 'x' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'x' の意味が変更されるのを避けるためです。」と怒られます。 一方、Hoge2の場合には怒られません。 Hoge2内でx=1;ではなくint x=1;と再宣言しているにもかかわらず怒られないのは、Hoge1が厳格にスコープ管理している点からみると意外に感じられます。 http://www.atmarkit.co.jp/ait/articles/0210/16/news001_5.html の記述を見ると、この記事が書かれた2002年ごろにはHoge2もNGだったような印象を受けるのですが、変化があったのでしょうか? この辺りの事情に詳しい方がおられましたらよろしく、お願い申し上げます。 class Class1 {    private void Hoge1()    {       int x;       {          int x = 2; // これはNG!。「ローカルの変数 'x' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'x' の意味が変更されるのを避けるためです。」と怒られる。       }    }    int x;    private static void Hoge2()    {       int x=1; //これはOK!親にぶらさげた変数が通る。    } }

  • ローカル変数を戻り値に使うと良くない C#

    C#2008で以下のように、Dumpメソッドを使った場合、 return sb.ToString();としていますが、 昔ローカル変数を戻り値に使うと良くないという 記憶があったのですが、正確なことはすっかり忘れてしまい 確か値型なら問題ないと思ったのですが、 以下の方法は正しくないでしょうか? 戻り値にこだわったのは、使えれば便利かなという程度です。 namespace Modorichi { public struct Test { public int a; public PlayInfo(string dummy) { a = -1; } public string Dump() { StringBuilder sb = new StringBuilder(); sb.Append(String.Format("a=[{0}]\n", this.a)); return sb.ToString(); } } }

  • C言語のプログラムについて。

    #include <stdio.h> int main(void) {   int hoge,piyo;   printf("数値を入力せよ。:");   scanf("%d",&hoge);   piyo = hoge % 2;   if (piyo == 0) {     printf("%dは、偶数。\n",hoge);   } else {     printf("%dは、奇数。\n",hoge);   };   return 0; } という、プログラムが、実行できません。 といって、エラーメッセージがでてくれないので、困っています。 ひょっとして、非常に初歩的なミスという気もするのですが。 これはよかった!という、C言語に関する書籍、また、コンピュータのシステムに関する書籍がありましたら、合わせてご教授ください。

  • C言語のグローバル変数の初期化について

    C言語において int a = 1; // 動的グローバル変数 static int b = 2; //静的グローバル変数 funcA(){ int c = 3; // 動的ローカル変数 static int d = 4; //静的グローバル変数 ・ ・ ・ } 上記のように各種変数を初期化したとします。 "c"のような動的ローカル変数であれば、funcA()が呼ばれたときに毎回初期化されますよね? では ・"d"のような静的ローカル変数は、初めてfuncA()が呼ばれたときに初期化されるのですか? ・"a","b"のyほうなグローバル変数は、どのタイミングで初期化されるのですか? 以上2点について伺いたいと思います。 ちなみに、組み込み機器むけのソフトウェアを想定しています。

  • C言語の基本的な質問ですが、関数へのポインタの宣言

    関数へのポインタの質問です。 下のように、関数へのポインタを使ったプログラムを書きました。 (関数へのポインタを理解するためのものなので、実用的な意味はありません。(*^_^*) また、このプログラムはコンパイルもリンクも実行も問題なく出来ます。) #include <stdio.h> int add_func(int,int); (*func_p0) (int,int); int main(void) { int (*func_p1) (int,int); int (*func_p2) ( ); int hoge0,hoge1,hoge2; func_p0=add_func; hoge0=func_p0(3,5); printf("0 : 3+5は%d\n",hoge0); func_p1=add_func; hoge1=func_p1(3,5); printf("1 : 3+5は%d\n",hoge1); func_p2=add_func; hoge2=func_p2(3,5); printf("2 : 3+5は%d\n",hoge2); return(0); } int add_func(int x, int y) { return(x+y); } func_p0のように戻り値の型を書かない場合と、func_p1やfunc_p2のように戻り値の型を書くのとでは何が違うのでしょうか。 func_p0は外部変数ですが、自動変数にする(main関数の中で同様に宣言。)とコンパイルエラーになります。 それはなぜですか。 func_p1のように引数の型が書いてあるのと、func_p2のように引数の型が書いていないのでは何が違うのでしょうか。 int (*func_p2) ( );というのは、int (*func_p2) (void);とは違うんですよね?

  • C言語の質問です。

    下記のコードでコンパイルすると成功しますが、実行時にエラーになります。 #include <stdio.h> int series(void); int main(void) { int i; for(i=0; i<10; i++) printf("%d ", series()); return 0; } /* これは正しくない */ int series(void) { int total; total = (total + 1423) % 1422; return total; } 解説には『ローカル変数の値はその関数が呼び出されている間だけ保持されます。 このプログラムはseries()関数を使ってある数列を作ろうとしていますが、 数列のそれぞれの数値を計算するのに1つ前の数値を使おうとしています。 しかし、変数totalの値はseries()の各関数呼び出しをまたがって保持される ことはないため、意図したとおりには動いてくれません。』とあります。 ローカル変数がその関数が呼び出されている間だけ保持されるのはわかりますが、 そのあとの解説の意味がわかりません。 どなたか詳しく解説していただけないでしょうか?お願いします!!

  • C言語で文字列操作を忘れてしまいました。

    長い間スクリプト言語ばかりやっておりまして、C言語に戻ると、文字列を返す 関数を作ろうとしましたが、お恥ずかしいながらできませんでした。 ローカル変数の値を戻り値に使おうとして、それがwarningになったり、動作が不安定になったりして、文字列を返す仕組みを完全に忘れてしまっていました。 例えば、"test"と言う文字列を返す関数を書きたいのですが、メモリ操作も考えた サンプルをだれか教えて欲しいです。 int main(void) { printf("%s", 「関数名」); }

専門家に質問してみよう