• ベストアンサー

標準入力からデータを受け取ってランダムファイル処理させたい

LINUXでCを使っています。 catでデータを標準出力させ、データ解析プログラムで標準入力から受け取り、そのデータをfseek関数を使ってランダム処理させようとしているのですが、うまくいきません。 具体的には、入力データをfseek関数でファイルポジションを一字分戻らせる処理をさせようとしています。でも、標準入力からデータを受け取るとfseekでファイルポジションを戻してやろうとしても戻りません。 fseekを使うには、一度データをファイルに落とし、fopenで開けてやるしか方法がないのでしょうか?

  • amu
  • お礼率51% (47/92)

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

  • ベストアンサー
  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.2

「1文字分限定」ということならungetc()で戻すことが出来ます。 ただし、RAWモードになっている時やI/OバッファにNULLが設定されている時にはおかしな挙動をすることがあります。 「1文字分限定でない」という場合ならいったんファイルに書き出すしかないでしょう。

amu
質問者

お礼

おそくなりすみませんでした。早速試します。

その他の回答 (2)

  • yatokesa
  • ベストアンサー率40% (201/496)
回答No.3

>ファイルポインタではなく、ファイルポジションがない、でしょうか? あ゛っ。そです。読み替えてください。すみませんでした。

  • yatokesa
  • ベストアンサー率40% (201/496)
回答No.1

標準入力ではファイルポインタがないので fseekは使えません。一旦ファイルに落とすか、内部データとして保持し、参照するしかないと思います。

amu
質問者

補足

早速のお返事ありがとうございます ファイルポインタではなく、ファイルポジションがない、でしょうか? 標準入力でもファイルポインタはstdinとして存在します。

関連するQ&A

  • C言語のfopen関数とfseek関数についてお尋ねします。

    fopen関数について オープンモードは様々ありますが、既存のファイルをバイナリモードで書き換えるということは出来ないのでしょうか? オープンモードが、「wb」などの場合は既存のデータを上書きしてしまって、内容が消えてしまいます。 かと言って、「ab」で開くと最後から追加されてしまいます。 fseek関数を使って、場所を指定しても言うことを聞いてくれませんでした。 既存のファイルの途中部分を少し書き換えるだけの作業は、出来ないのでしょうか? fseek関数について バイナリモードで開いているときに、ファイルの全体を知りたい時に次のように書いたら間違いなのでしょうか? fseek(FILE *stream, 0, SEEK_END); ftell(FILE *stream); fseekで最後のポジションに移動させて、ftellで最後のカレントポジションを調べるという方法は使えるのでしょうか? 以上2点よろしくお願いします。

  • PHPの標準入力処理について

    お世話になります。 RedHat7.3に標準で入っているphp4.1.2を使って コマンドライン用の対話的なツール作成を 考えておりますが、上手くいきません。 以下サンプルです。 >>test.php --------------------------------------- #!/usr/bin/php -q <?php set_time_limit(0); function read($length){ $input1 = fopen("php://stdin","r"); $input2 = trim(fgets($input1, $length)); fclose($input1); return $input2; } echo "enter your name \n"; $name = read(64); echo "your name is $name \n"; echo "enter your age \n"; $age = read(64); echo "your age is $age \n"; ?> -------------------------------------------------- 上記test.phpに実行権を与え $ ./test.php を実施すると以下のようになる予定でした 1.enter your name を出力 2.標準入力から名前(hoge)を入力 3.your name is hoge を出力 4.enter your age を出力 5.標準入力から年齢(24)を入力 6.your name is 24 を出力 このようにはならずに実際は 2 -> 5 -> 1,3,4,6 と標準入力が先でecho文が最後に ドバットと出力されてしまいます。 出力される内容は、入力した文字が きちんと反映されています。 どうすれば思い通りの順番で 処理されるのかご存知の方が おりましたらご教授ください。 宜しくお願いします。

    • ベストアンサー
    • PHP
  • リダイレクションで標準入力を変更できない

    入門UNIXシェルプログラミングを読んで 今まで眠らせていたレッドハットのいろんな操作方法を学習しています。 今は第4章リダイレクションによるファイル操作を読み進めています。 >を使って標準出力を変更する方法を学習しました。 また、<を使って標準入力を変更する方法も学習しました。 しかし、本の例のとおりに入力しても、標準入力を変更できませんでした。 $cat xyz abc nnn $ls < xyz aaa abc nnn xyz xyzで指定したabc nnnのリストを表示させたいのに 全てのリストが表示されてしまいます。 つまり、< xyz以降が無視されて、引数なしのlsが実行されてしまいます。 他にも私が知ってるコマンド(echoやcat)でも標準入力が変更できるか試してみたのですが、やはりダメでした。 $ echo < xyz $ cat < xyz abc nnn echoは空行を表示します。 catの場合は、<だけが無視されてcat xyzとして実行されるようです。 どなたか教えてください。 このリダイレクションの使い方は合ってますよね。 どうやれば、標準入力を変更できるのですか。

  • 処理結果(標準出力と標準エラー出力)をファイルと画面の両方に出力する方

    処理結果(標準出力と標準エラー出力)をファイルと画面の両方に出力する方法はありますか? 当方 処理結果(標準出力と標準エラー出力)をファイルに出力する際に iroirona_command > log.log 1>&2 ・・・ファイルに出力されるが画面には表示されない。 iroirona_command ・・・画面には表示されるがファイルには出力されない。 と書いて標準出力と標準エラー出力を出力させているのですが、 ファイルと画面の2つの出力先に出力したいと考えています。 可能なのでしょうか? 環境 Windows XP SP3

  • 出力ファイル名を標準入力から指定したい。

    初心者ですが、よろしくお願いします。 perlで、data.txtというファイルへ $protein の 情報を書き込みたい場合、以下のようにすれば 良いということはわかるのですが、 open(OUT, ">data.txt"); print OUT $protein; では、出力ファイルを data.txtではなく、プログラムを 実行させる度に標準入力から指定してやることはどうやれば できるのでしょうか?

    • ベストアンサー
    • Perl
  • ファイルにデータを書き込むときにもとのデータを消去

    データを1個のファイルに保存しているのですが、データを更新するときに現在書き込まれている中身を一度消去してから書き込みたいのですが、どのような方法がいいのでしょうか。 $fo=@fopen($book,"r+") or die(); flock($fo, LOCK_EX); ~読み込んで書き込み用のデータ処理~ fseek($fo, 0); fwrite($fo, $buff); flock($fo, LOCK_UN); fclose($fo); と、していますが、先頭に追加されるだけで、これまでのデータが残ったままです。 一度ファイルをまっさらにするか、一度ファイルを削除して新規に作成しようかとも思いましたが、アクセス数が多くなる予定なので、あまり良い方法ではないと考えています。 このような場合、一般的にどうすればいいかご教授願えればと思います。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • ファイルへの出力

    現在VisualC++でアドレス帳を作成しています。 一人を構造体として、各メンバに値を入力し、ファイルに出力するプログラムを組みましたが、出力ファイルには文字化け?のようなものが出てきてしまいます。 メンバ変数に char* name があり、最初に name = (char *)malloc(NameLength); としてメモリを確保し、コンソール画面では全角入力によりデータを格納しています。 また char* age としてメンバを定義した場合は半角入力でデータを与えています。 これらを標準出力fopen("filename.txt", "w");より出力した場合変なもじ?が出力されてしまいます。 出力は fputs関数を利用しています。 文字化けを防ぐ方法はないでしょうか?

  • 同じデータファイルなのに、linuxとMacで値が違ってしまうのはなぜ?

    職場でlinux(初心者です), 自宅でMacを使っています。 同じCプログラムを使って、同じバイナリデータファイルから数値を読み出したところ、職場のlinuxでやった場合と自宅のMacでやった場合では、違う値が出てきてしまいます。読み込むデータは1byteのバイナリなので、エンディアンは関係ないと思うのですが、ほかに原因があるのでしょうか?そばに詳しい人がおらず、困っています。どうしてこういうことが起きるのか、また、どうやったら解決できるのか、どなたか詳しい方、ぜひアドバイスをお願いします。 以下、プログラムの説明とプログラムの一部です。 バイナリデータファイルから、dposition[i]番目の1byteのデータをそれぞれ読み込み、それぞれ別の出力ファイルfo[i]に書き込みます。dposition[i]はPOSITION_NUM個あり、従って、出力ファイルもPOSITION_NUM個用意しています。dposition[i]で指定した場所はとびとびの不連続な場所です。データを読み込むときは、0番目から、一番大きいdposition[i]番目(=maxnum番目)のデータまで、すべてをarray[datanum]に読み込み、書き出すときにdposition[i]番目のデータのみを書き出すよう指定しています。読み込むバイナリファイルはFILE_NUM個あり、すべて同じ形式です。順次開いて読み込み出力を繰り返します。以下プログラムの一部です。 for (j = 0; j < FILE_NUM; j++) { if(NULL == (fi = fopen(fn_in[j],"rb"))) { printf("Cannot open input BISE File\n"); exit(1); } for (datanum = 0; datanum < maxnum+1; datanum++) { array[datanum] = fgetc(fi); } for (i = 0; i < POSITION_NUM; i++) { fprintf(fo[i],"%d\n",array[dposition[i]]); } fclose (fi); } 以下、linuxでやった場合の出力を左、Maxでやった場合の出力を右に並べて書きます。 104 104 100 100 74  22 83  83 60  60 0   0 106 106 79  33 167 167 182 182 180 0 188 188 ... ... 3,8,11番目が違う数字が出力されます。繰り返しますが、プログラムと入力ファイルは同じものです。 linuxでもMacでもターミナルでコンパイル、実行しています。 コンパイラのバージョンは、gccで検索したらなんだかたくさん出てきてしまって、どれが使っているコンパイラのバージョンなのかよくわかりませんでした。 ちなみに、MacはIntel系の方です。 ほか、アドバイスいただくにあたって、何か必要な情報があればご指摘ください。 ぜひよろしくおねがいします。

  • Linux上でtcpdumpの出力をperlで処理したいと考えています

    Linux上でtcpdumpの出力をperlで処理したいと考えています。 下記のようにtcpdumpの標準出力をperlの標準入力で受け取ろうとしても tcpdumpの処理が終わらないためパイプ(|)経由でperlにデータが渡ってきません。 [test.pl] $|=1; foreach(<>){ print "--- $_"; } exit; Linux上のコマンド tcpdump -l | ./test.pl これをteeに置き換えるとtcpdumpの出力はリアルタイムに表示されます。 tcpdump -l | tee a.log 質問:perlでteeを作ることはできますか?

    • ベストアンサー
    • Perl
  • 入力フォームで入力されたデータをHTMLファイルで出力させたい。

    入力フォームから入力されたデータを、 HTMLファイルで出力しようと考えています。 ブラウザで表示させるのではなく、 ファイルとして出力したいです。 いろいろググりましたが、サンプルが見つかりませんでした。 可能でしょうか。宜しくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう