入出力共用ができない理由とは?

このQ&Aのポイント
  • 入出力共用ができない理由とは?プログラム中でファイルの読み書きを行う際に、一部の処理で入出力共用ができない場合があります。
  • 具体的な例として、カウンターを作るプログラムで入出力共用ができないケースがあります。一部の処理では、ファイルを読み込みながら書き込む必要があるため、入出力共用ができなくなります。
  • 入出力共用ができない場合は、一度ファイルを読み込んでから書き込む方法を取ることで回避できます。しかし、本には入出力共用ができると書いてある場合など、状況によっては混乱を招くこともあります。
回答を見る
  • ベストアンサー

入出力共用が出来ないんです

カウンターを作ろうとしてるんですけど、入出力共用が出来ないんです。 その部分は open INOUT, "+>$txt";       #$txtはテキストファイルへのアドレス $count = <INOUT>; $count++; print INOUT $count; close INOUT; ってやっています。ここだけコマンドプロンプトで試しているんですが、上手く動きません。"+>$txt"を"+<$txt"としたり、">+$txt"にしたり、最後には、">+<$txt"といろいろ試したんですがダメでした。 ちなみに open IN, "<$txt"; $count = <IN>; close IN; $count++; open OUT, ">$txt"; print OUT $txt; close OUT; ってやると動きます。別にこれでもいいんですが、本には共用出来ると書いてあるのに出来ない、なんかすっきりしません。 入出力共用って出来ないんでしょうか?

  • CGI
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
noname#25358
noname#25358
回答No.1

 共用オープンはプロでもそうそうには使いません。  面倒臭いんで。まあ、使う人は使うかもしれませんが。  ファイルの操作には、「現在操作位置」というものがあります。いわゆる「シーク位置」と呼ばれるものです。  たとえば、4行のテキストファイルを順に読み出すと、1行ずつ順番に読まれます。途中で2行同じものが入ってきたりはしません。  これはなぜかというと、1回読み込みを行うと、プログラムが自動的にシーク位置を次の行へ移動してくれるからです。  また、書き込みのときも同様で、「書き込み位置」をシステムが自動的に管理してくれています。  しかし、入出力共用オープンの場合、これをプログラマーがやってあげなければいけません。  たとえば質問の例だと、オープンした時点では「書き込み位置」が定義されていないので、プログラムは混乱してあらぬところにデータを書き込むとか、まったく書き込まなかったりとかしてしまいます。  ですので、プログラマーがどこに書き込むかを指定してあげるのです。 open INOUT, "+<$txt"; $count = <INOUT>; $count++; seek(INOUT, 0, 0); print INOUT $count; close INOUT;  それから、読み書き共用モードの指定は「+<」こうです。  「+>」これだとファイルの内容が壊れますのでご注意を。  まあ、プログラムをすっきりさせる意味で、共用モードはあんまり使わない方がいいかもしれません。好きずきですが。

zeyper
質問者

お礼

そうだったんですか、ありがとうございます。 素直に読み込みが終わった後に、また書き込むようにします。 seek関数ってそういうときに使うんですね、本で読んだけどいつ使うのかよく分から無かったんですよ。 ちなみに、僕が読んだ本だと「+>」になってました。(笑) それでは、丁寧な回答ありがとうございました。m(_ _)m

関連するQ&A

  • ファイルの入出力が出来ません。

    perlの初心者です。 cgiを作ろうとしています。 標準出力には出力できても、ファイルの入出力が出来ません。 #!/usr/bin/perl open(OUT,">>test"); print OUT "test data"; close (OUT); と実行しても、エラーもでないのですが、ファイルも作られず、書き込みもされません。 しかし、コマンド名'test'としてセーブして、プロンプトから'perl test'とするとファイルに書き込みされるようです。 perlの設定の問題なのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Perl
  • lockについて

    $file = 'file.log'; ------------------------------------ sub a{ &lock;ロック 1: open(IN, $file); # ファイルを開く 2: $count = <IN>; # カウンターを読み出す 3: close(IN); # ファイルを閉じる 4: $count++; # カウンターをひとつ増やす 5: open(OUT, "> $file"); # ファイルを開く 6: print OUT "$count\n"; # ファイルにカウンタを書き込む 7: close(OUT); # ファイルを閉じる 8: print "$count\n"; &unlock;ロック解除 } ------------------------------------ sub b{ 1: open(IN, $file); # ファイルを開く 2: $count = <IN>; # カウンターを読み出す 3: close(IN); # ファイルを閉じる } ------------------------------------ サブルーチンaではロック処理を行っていますが、 サブルーチンbでは書き込む処理がないためロック処理を行っていません。 読み込むファイルは同じでなのですが、 サブルーチンbにもロック処理を入れた方がいいのでしょうか?

    • ベストアンサー
    • Perl
  • Perlでテキストファイル読み込み

    基本的な質問ですみません。 サーバ上のテキストファイルを読み込んで ローカルのテキストファイルに書き込むというだけなのですが 何度やってもできません。 以下プログラムですが #!usr/bin/perl open(IN,"http://*****/***/***.txt"); $file = <IN>; close(IN); open(OUT,"> a.txt"); print(OUT "$file"); close(OUT); サーバのアドレスは、URLうってみて見れたのでhttp://***(以下略)であってると思います。 サーバのテキストにはchmodで777と権限を与えました。 プログラムに問題あるのでしょうか。 この場合考えられる原因を教えてください。

    • ベストアンサー
    • Perl
  • アクセスカウンタでリロード時のカウントされるのをやめたい!

    自分のPCでIIS5.0をインストールして CGIの作成練習をしています。 簡単なアクセスカウンタを作ったのですが、 どっかのをコピーしただけ。。。 sub counter{ #(読込み) open (IN,"<./count.dat"); $raikyaku = <IN>; close (IN); $raikyaku++; #(書き込み) open (OUT,">./count.dat"); print OUT $raikyaku; close (OUT); } これを、更新ボタンを押した時にカウントされない ようにしたいです。 また、BBSに埋め込もうと思っているので、 投稿ボタンで再表示された場合も カウントされてほしくありません。

  • Perlを使って、大文字小文字関係なく、重複行を削除したい。

    現在、下記のコードで重複行を削除し、ファイルを作成しているのですが、 AAA aaa AaA などのように大文字、小文字が混じっている場合は重複とはみなさず削除の対象になりません。 こういった場合も重複とみなして削除させたいのですがどのようにすればいいでしょうか? open(IN, "INfilename.txt"); open(OUT, ">Outfilename.txt"); while(){ if(!exists($count{$_})){$count{$_}++;print OUT $_;} } close (IN); close (OUT);

    • ベストアンサー
    • CGI
  • @niftyホームページでのアクセスカウンタ(perl)

    すごく簡単なアクセスカウンタなのですが実行できません。 ちなみに、perlスクリプトは、count.plというファイルに、 #!/usr/local/bin/perl $countfile="count.dat"; open IN,"$countfile"; $count=<IN>; close IN; $count=$count+1; open OUT,">$countfile"; print OUT $count; close OUT; print $count; html内の記述は、 あなたは、<!--#exec cmd="http://hpcgi3.nifty.com/******/count.pl"-->人目 plファイルを置くディレクトリは間違っていないようです。 perl、@niftyに詳しい方回答お願い致します。

    • ベストアンサー
    • Perl
  • 初心者で、困っています。(文字化け)

    すみません、すごく初歩的なことで困っています。 本を見ながら、下のようなものを書いたのですが、 出力すると、文字化けをしてしまいます。ウィンドウズの環境で、Perlは5.8を使い、読み込みのテキストはUnicodeです。どのようにすれば、文字化けをしないで、読み込めるのでしょうか。 open ( IN , "LBa3_00028.txt" ) or die; open ( out , ">out.txt" ); while ( $line = <IN>){ print out "$line\n"; } close(out); close(IN);

    • ベストアンサー
    • Perl
  • どうしてもインターナルサーバーエラーになります

    #!/usr/bin/perl # アクセスカウンタ print "Content-type: text/html; charset=Shift_JIS\n\n"; # カウントファイルから読み込み open(IN, "counter.txt"); $count = <IN>; close(IN); # カウント増加 $count++; # カウントファイルに書き込み open(OUT, "> counter.txt"); print OUT $count; close(OUT); print <<EOL; <html> <body> <p>あなたは $count 人目のお客様です</p> </body> </html> EOL ------------------------------------------- ↑は、 http://ponk.jp/perl_bbs/index.php?page=2 このサイトからの引用なのですが、どう頑張っても このアクセスカウンターCGIにアクセスしてもインターナルサーバーエラーになってしまい助言お願いにきました。。 ちなみにこのアクセスカウンター編の前の「ブラウザに文字列を表示する」のところでは、しっかりCGIをサーバーにアップロードして ブラウザに表示させることができましたので、なぜアクセスカウンター は表示してくれないのか途方にくれています。 ・パスの確認 ・属性の確認 ・アスキーモードなどの送信形式の確認 等など、あやしいところは全てチェックしてみましたがダメでした・・・。 ブラウザに文字列を表示させるだけの事はできたのになぜ、アクセスカウンタは表示させれないのか全くわかりません。 どなたかわかる方いらっしゃいましたらすいませんがどうか教えてください。よろしくおねがいします。

  • flockが使えない場合のスクリプトを教えて下さい

    こんにちわ。私はwindows meなのですがflockが使えないようなのでその場合はどのようなスクリプトで表現したらよいのか方法があったら教えて下さい。このflockの部分に代わるものを教えて下さい、又他の方法があればアドバイス下さい。宜しくお願いします。 open(COUNT,"+<countdata.txt") || die "File'countdata.txt'Open Error\n"; #flock(COUNT,2); $counter=<COUNT>; $counter_new=$counter+1; print"$counter_new\n"; seek(COUNT,0,0); print COUNT"$counter_new\n"; close(COUNT); #flock(COUNT,8);

    • ベストアンサー
    • Perl
  • borlandC++で膨大データの入出力ができない

    borlandC++を試してますが、ifstream等を利用してファイル入出力を試してますが、プロンプトを用いて、入力データが多すぎるとコンパイルは通りますが実行exeが拒否反応を起こし処理が止まってしまいます。 データが7万行以上ぐらいに達すると拒否反応を起こします。 自分がやろうとしてるのはそれを遥かに凌ぐ何百万行のデータの入出力処理を行いたいのですがこれでは不可能です。 どうして膨大データの入出力ができないのでしょうか? 自分の試したファイル入出力のプログラムソースと問題の読み込んだデータの内容も下に貼り付けます。 またソース中の処理で上記とは別のエラーを起こしたものがあり、入力データを一行毎に格納する配列 dag[b]  をprintfで表示させようと以下の様に記述しましたが printf("[%d] %s\n", b,dag[b]); もデータが7行以上になるだけでエラーを起こして止まります。 どうか膨大データの入出力とprintfのエラーの解決方法について教えて下さい。 宜しくお願いします。 #include <iostream.h> #include <fstream> main() { string dag[100000]; string LineData; int b=0; ifstream in("rrs.txt", ios::in); if(!in){ printf("エラー\n"); exit(1); } while(!in.eof()){ printf("データ\n"); in >> dag[b]; printf("[%d] %s\n", b,dag[b]); b++; } in.close(); ofstream out; out.open ("WRT.txt"); for(int i=0;i < b;i++)out << dag[i] << endl; out.close(); return 0; } #読み込んだデータ内容 2011/12/09,16:00:00,77.48,77.50,77.48,77.50 2011/12/11,17:00:00,77.66,77.66,77.54,77.61 2011/12/11,18:00:00,77.61,77.61,77.58,77.59 2011/12/11,19:00:00,77.59,77.64,77.59,77.63 2011/12/11,20:00:00,77.63,77.65,77.61,77.63 2011/12/11,21:00:00,77.63,77.63,77.58,77.60 2011/12/11,22:00:00,77.60,77.62,77.60,77.60 2011/12/11,23:00:00,77.61,77.64,77.60,77.64 2011/12/12,00:00:00,77.64,77.64,77.61,77.63 2011/12/12,01:00:00,77.64,77.64,77.56,77.58 2011/12/12,02:00:00,77.58,77.63,77.57,77.59 2011/12/12,03:00:00,77.59,77.69,77.58,77.66 2011/12/12,04:00:00,77.67,77.84,77.67,77.83 2011/12/12,05:00:00,77.82,77.90,77.74,77.80 2011/12/12,06:00:00,77.80,77.84,77.75,77.81 2011/12/12,07:00:00,77.81,77.82,77.75,77.78 2011/12/12,08:00:00,77.78,77.97,77.76,77.97 2011/12/12,09:00:00,77.97,77.97,77.83,77.91 2011/12/12,10:00:00,77.90,77.93,77.76,77.80 2011/12/12,11:00:00,77.79,77.86,77.72,77.86 2011/12/12,12:00:00,77.86,77.88,77.83,77.84 2011/12/12,13:00:00,77.84,77.89,77.83,77.89

専門家に質問してみよう