テキストファイルの読み込みとファイルポインタについての質問

このQ&Aのポイント
  • テキストファイルの読み込みとファイルポインタについて質問です。最近PHPを勉強し始めました。fgets()とfseek()についてわからないことがあるので教えて頂けないでしょうか。
  • PHPでテキストファイルを読み込み、指定した行を表示したいです。fgets()とfseek()を使用して2行目を表示しようとしていますが、うまくいきません。
  • 質問:PHPでテキストファイルを読み込み、指定した行を表示する方法について教えてください。fgets()とfseek()を使用して2行目を表示しようとしましたが、うまくいきませんでした。正しい方法を教えてください。
回答を見る
  • ベストアンサー

テキストファイルの読み込みとファイルポインタについて質問です。

テキストファイルの読み込みとファイルポインタについて質問です。 最近PHPを勉強し始めました。 fgets()とfseek()についてわからないことがあるので教えて頂けないでしょうか。 現状以下のテキストとPHPファイルを用意しています。 PHPに2行目のbを表示させたいのですが、思ったように表示をさせることができません。 fgets()は"現在のファイルポインタから次の1行を取得" fseek()は"ファイルポインタを指定したバイト数分移動する"と調べてわかりました。 この二つを使って2行目を指定してbを表示したいのですがうまく表示されて困っています。 test.phpのコメントの★の部分がわからない箇所になります。 おそらく根本的な考え方が間違っていると思うのですが…いろいろ調べたのですがわかりませんでした。 申し訳ありませんがご教授願えないでしょうか。 ----------------- new.txt ----------------- a b c d e ----------------- ----------------- test.php ----------------- <?PHP $new_file = 'new.txt'; $fpt = fopen($new_file,'r'); // ファイルオープン直後のポインタ位置 echo '現在の位置=行指定'.ftell($fpt).'<br>'; print fgets($fpt).'<br>'; // ポインタを5進める fseek($fpt,5); echo '現在の位置=行指定'.ftell($fpt).'<br>'; // ポインタの位置確認 print fgets($fpt).'<br>'; // ★ここでeを表示したい // 現在の位置からポインタを3戻す fseek($fpt,-3,SEEK_CUR); echo '現在の位置=行指定'.ftell($fpt).'<br>'; // ★行指定が5-3なので2に…ならないです。 print fgets($fpt).'<br>'; // ポインタを先頭へ rewind($fpt); echo '現在の位置=行指定'.ftell($fpt).'<br>'; // ポイントが先頭にきたか確認 print fgets($fpt).'<br>'; // ポインタを最後へ fseek($fpt,0,SEEK_END); echo '現在の位置=行指定'.ftell($fpt).'<br>'; // ★new.txtはabcdeの5行なので5になると思いきや18に… print fgets($fpt).'<br>'; fclose($fpt); // ファイルを閉じる ?> ----------------- ----------------- 実行結果 ----------------- 現在の位置=行指定0 a 現在の位置=行指定5 現在の位置=行指定3 b 現在の位置=行指定0 a 現在の位置=行指定18

  • PHP
  • 回答数3
  • ありがとう数3

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

  • ベストアンサー
  • joy_28
  • ベストアンサー率84% (45/53)
回答No.2

RIN_LINさん、 以下でいかがでしょうか? <?php $lineArray=array();//読み込んだ行を入れ込む、配列生成 $n=0;//行数のカウンター $file=fopen('new.txt','r');//読み込み対象ファイル名を、new.txtとする flock($file,LOCK_SH); while (!feof($file)){//行末まで、1行単位で、読み込む $line=fgets($file); $n++;//行数をカウント array_push($lineArray,$line);//配列$lineArrayに、push } print $lineArray[1];//0,1,2・・・の1番目を表示する flock($file,LOCK_UN); fclose($file);

RIN_LIN
質問者

お礼

お返事いただきましてありがとうございます。只今仕事中です。 ソース確認させて頂きました、なんだかうまくいけそうな気がします。 帰宅しましたら早速試させて頂きます。 結果が出ましたらまた連絡させて頂きます。 取り急ぎお礼をさせて頂きました。ありがとうございます。

その他の回答 (2)

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.3

1. $lines = file($new_file); echo $lines[1]; 2. $fpt = fopen($new_file, 'r'); fgets($fpt); echo fgets($fpt); ...

RIN_LIN
質問者

お礼

ご回答ありがとうございました。 2番目にお返事いただいた方のソースで解決致しましたので閉めさえて頂きます。 お二人とも行指定の方法を教えていただいてありがとうございました。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

単に改行コード分を計算に入れてないだけでは。 ftellやfseekは行を意識しませんし。 バイナリエディタでそのファイルを見てみると分かりやすいかも。

RIN_LIN
質問者

お礼

返事が遅くなってしまい申し訳ありませんでした。 なるほど、行を認識してくれなかったのですね一つ勉強になりました。 fseekは"バイト数移動"というようなことも書かれていたので気になっていたのですが、そういうことだったのですね。 調べた所フリーのバイナリエディタがいくつか見つかりましたので帰宅したら早速試してみます。ありがとうございました。

関連するQ&A

  • PHPでファイルポインタの移動

    現在。[EOF]になるまで1行読込んでは、ファイルポインタを移動させ すべての行を出力しています。 これをテキストの[EOF]よりも1行上のbbbbbbbbがある行(見た目上の最終行)のみを 出力したいのですがどうすればいですか? while(!feof($filepointer)){ $line = fgets($filepointer); print($line."<br />"); } ~log.txt~ aaaaaaaaaaaaa[改行コード] bbbbbbbbbbbbb[改行コード]←ココのみ取り出したい [EOF]

    • ベストアンサー
    • PHP
  • テキストファイルの文字列の削除

    1行あたりIPアドレスが1つ書いてあるテキストファイルから、指定したIPアドレスを削除するプログラムを作成しています。 r+モードでfoepnした後にfgetsで一行ずつ読み取り、指定されたIPアドレスかどうかをチェックし、該当すればその行をNULLで埋め尽くしているのですが、サクラエディタなどで開くとその行が削除ではなくNULL文字で埋め尽くされているといった現象になります。 削除するにはどうすればよいでしょうか? ipaddress.txt --------------------- 192.168.0.1(\n) 192.168.0.2(\n) 192.168.0.3(\n) --------------------- 以下、コード bool DeleteAllowIP(char *ipaddr) {   FILE *fp;   char szBuf[256];   int leng = 0;   long posi=0;   // 初期化   FillMemory(szBuf, sizeof(szBuf), 0);   // ファイルオープン(追記)   if(fopen_s(&fp, AllowPath, "r+"))     return FALSE;   // 削除   while (NULL != fgets(szBuf, sizeof(szBuf), fp)){  // 1行読み取る     if(NULL != (strstr(szBuf, ipaddr))){  // 削除IPに合致するIPを検索       fseek(fp, posi+1, SEEK_SET);  // 削除する先頭行セット       leng = strlen(szBuf) - 1;  // 改行を除く文字数を取得       while(leng>=0){   // 文字数分'\0'をセット         fseek(fp, posi+leng-1, SEEK_SET);         leng--;         fputc('\0', fp);       }       fseek(fp, posi+1, SEEK_SET);  // 次の行の先頭にセット     }     posi = ftell(fp);   }   // ファイルクローズ   fclose(fp);   return TRUE; }

  • fwriteで書き込み

    やりたいことは・・・下に書いていきます。 何がおかしいのか教えてください。 $fp = fopen("example.txt", "r+"); fopenでexample.txtを読み書き可能で開きます。 返り値はポインタですよね。 $fseek = fseek($fp, -3, SEEK_END); $fpで開いたexample.txtのポインタを、ファイルの最後尾から3バイト戻したつもりです。 返り値は 0 成功 -1 失敗 $ftell = ftell($fp); で、今のポインタの位置を確認します。 返り値はポインタ。 fwrite($ftell,$write); $writeの内容を、example.txtの最後から3バイト戻ったところへ書き込み・・・のつもりなのですが。 専門分野ではありませんので、調べてもなかなか進まないです。 ご教授お願いします。

    • ベストアンサー
    • PHP
  • ページ表示ごとにカウントダウンをさせたい。

    こんばんわ。 こんなスクリプトを組んでみました。 phpは勉強を始めたばかりです。 <? echo "Hello world!!";?> <br> あなたのIPは <? echo $_SERVER["REMOTE_ADDR"]?> ですね? <br> ただいま<? print (date ("Y年m月d日(D) H時i分s秒"));?>です <br><br> <?php $fp = fopen ("count.txt","r+"); $count = fgets ($fp, 32); $count--; fseek($fp, 0); fputs($fp, $count); flock($fp,2); $count = sprintf("%05d", $count); fclose($fp); echo $count ?> ログファイルは初期値として、10としました。 が9までは正常に減っていくのですが、次に8にならずに 89になってしまいます。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • fopenでファイルを読み込み、その取り込んだファイルを置換や修正したい。

    こんばんわ。 AというファイルにBというファイルを読みこもうと思うのですがうまくいきません。 ■a.php <?php // ファイルを読み込み専用でオープンする $fp = fopen('b.php', 'r'); // 終端に達するまでループ while (!feof($fp)) { // ファイルから一行読み込む $line = fgets($fp); // 読み込んだ行を出力する print $line; // <br>の出力 print "<br>"; } // ファイルをクローズする fclose($fp); ?> ■b.php <div class="title">コンテンツ</div> <?php $amin = 1; //最小値 $amax = 4; //最大値 $randevent = rand($amin,$amax); //値を表示 if ( $randevent == 1) echo "たちつてと"; // else if ( $randevent == 2) echo "さしすせそ"; // else if ( $randevent == 3) echo "かきくけこ"; // else if ( $randevent == 4) echo "あいうえお"; ?> と、二つのファイルはこのような内容です。 もちろんincludeやリクワイヤーで取り込めばすむのでしょうが、fopenで取り込んで表示させたいのです。 このままの文章だとPHPの構文ごとHPに表記されてしまいます。 Printにしているからでしょうか? fopenでPHPの機能ごと取り込むには方法はありませんでしょうか? includeだと取り込んだ際にPHP構文の置換や修正がきかなくて困るんです。 fopenで取り込むとPHP構文を「あいうえお」の部分を「なにぬねの」にstr_replaceで置換できると思ったのです。 a.phpの中にfopenを使いb.phpの中のPHP構文を機能させる方法はありませんか?

    • ベストアンサー
    • PHP
  • テキストの内容を部分的にコピー

    十数行あるテキストファイルの内容を、 下5行だけ他のテキストファイルにコピーするプログラムを作りたいのですが、ファイルのアクセス位置をどうしたらよいでしょうか。 全体をコピーするところまでは出来たのですが、 下5行を指定するという部分がうまくいきません。 fseekを使えばいいかと思っているのですが、いい方法はないでしょうか。 よろしくお願いします。

  • FILE構造体のファイルポインタについて質問です。

    FILE構造体のファイルポインタについて質問です。 Microsoft VC++を使っています。 テキストファイル(1行の連続して文字が連なっている。)のn文字目からの文字を読み取る場合、fgetsでn-1文字目まで読み取ってから、fgetsでn文字目から読み取ればできるのですが、ファイルポインタを使用した場合について教えてください。 FILE *fp; fp = fopen("a.txt","r"); と宣言すると、fp->_ptrがファイルポインタになります。 この段階でfp->_ptrは0で、値を読み込みとエラーになります。(ファイルの実行が停止) fgets()で何文字でもいいから読み込むと、fp->_ptrにアドレスが読み込まれます。 fp->_ptrに加算してn-1文字目まで動かして、fgetsで文字を読み込めば読み込めるのですが、 ファイルの残りの文字数よりも読み込む文字数が大きい場合、その差分だけへ(アスキーコード205) が読み込まれます。 詳しく説明すると、テキストファイルにn文字目からabcdeという5文字があるとします。 n文字目から10文字読み込んだ場合、配列に格納される文字がabcdeヘヘヘヘヘになってしまいます。 へ(アスキーコード205)の数は最大でfp->ptrに加算した値となっています。 質問としましては (1)fp->ptrにアドレスが書き込まれるのはどのタイミングなのでしょうか? (2)なぜへ(アスキーコード205)が格納されてしまうのか? 分かる方、是非ご教授をよろしくお願いします。

  • PHP、外部ファイルにテキストを書きだす。

    こんにちは、皆様。 下記のソースを実行したいと思います。期待する結果としては、外部ファイルに行列に書き出すことです。 <?php $count_file="count.dat"; if(file_exists($count_file)){ $file = fopen("count.dat", "a") or die("file can not open"); $order_no = fgets($file) + time(); print $order_no; }else{ $file = fopen($count_file, "w") or die("file can not open"); $order_no = time(); } set_file_buffer($file,0); flock($file, LOCK_EX); fputs($file , $order_no); flock($file, LOCK_UN); fclose($file); ?> このソースの結果は配列として書き込まれてました。こんな感じです。 129835261512983526501298355377129835537912983566121298356635 このソースを実行する度にcount.datファイルに順次書き出したと思います。 1298352615 1298352650 1298355377 1298355379 1298356612 1298356635 まだまだPHP勉強中なのでわかる方教えてください。 (1)この行で$order_no = fgets($file) + time(); 改行記号をどう付ければ良いでしょうか? (2) C言語のようにポインターで指定しなければならないですか?書き方を教えてください。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • ファイル処理について

    大学の課題なのですが、何度取り組んでもエラーになるため、間違いのご指摘、または正答を教えていただけないでしょうか。 問題は以下のものです。 【問題】 ファイルから整数を読み込み,その値によってfpの読み込み位置をかえ,何度目の読み込みで0を読み込んだかを表示するプログラムを作成せよ. ファイルの内容の例 2,4,0, fpの読み込み位置を変えるにはfseekという関数を利用する. fseekの使い方: 現在の読み取り位置xだけずらすには, fseek(ファイルポインタ, x, SEEK_CUR); と記述する. STEP 1 データを一区切りで読み取る("2,"や"-4,"などの整数とコンマの組) 2 読み取ったデータに応じてfpを移動させる("2,"なら2移動,"-4,"なら-4移動) 3 0を読むまで繰り返す +++++*+++++fseek-exercise.c+++++*+++++ #include <stdio.h> int main(void){ FILE *fp; int c; int i; int count=0; char filename[60]; printf("ファイル名 :"); scanf("%s",filename); //ファイルを開く // (* ここに解答を書き加える *) while(1){ printf("読み込み前 : %ld\n",ftell(fp)); //fpから値を読む // (* ここに解答を書き加える *) printf("読み込んだ値は%dです\n",c); printf("読み込み後 : %ld\n\n",ftell(fp)); //読み込み位置をずらす // (* ここに解答を書き加える *) } printf("%d回目です.",count); fclose(fp); return(0); } // 以上になります。 自分で作ったプログラムは以下のようになりました。 #include <stdio.h> int main(void){ FILE *fp; int c; int i; int count=0; char filename[60]; printf("ファイル名 :"); scanf("%s",filename); //ファイルを開く // fp = fopen(filename,"r"); if(fp == NULL){ printf("cannot open\n"); exit(1); } while(1){ printf("読み込み前 : %ld\n",ftell(fp)); //fpから値を読む // c = fgetc(fp); printf("読み込んだ値は%dです\n",c); printf("読み込み後 : %ld\n\n",ftell(fp)); //読み込み位置をずらす // if(c > '0' || c< '9'){ i = atoi(&c); count++; if(i == 0){ break; } fseek(fp,i,SEEK_CUR); } } printf("%d回目です.",count); fclose(fp); return(0); } // どこを訂正していいのかわかりません。 どうぞ、よろしくお願いいたします。

  • ファイルの読み込みとnl2br

    いつもお世話になっております。 ちょっとわからないことがあり質問させていただきます。 ファイルの読み込みで $fp= fopen("1.txt","r"); list($i,$j,$k,$l) = explode(",",fgets($fp)); で1.txtの中身は 1,2,3,aaa\r\nbbbb というカンマ区切りのファイルになっています。 しかし print nl2br($l); をブラウザで見ると\r\nがそのまま表示されてしまいます。 gettype($l)はstringと表示されます。 ちなみに $l="aaa\r\nbbbb"; print nl2br($l); は改行されたものが表示されます。 php4.3.10でレンタルサーバです。 ファイルからの取り出し方に問題があるのでしょうか? もしくはデータのの書き出し方に問題があるのでしょうか?(1.txtはフォーム上から書きこみます) ご教授いただければ幸いです。

    • ベストアンサー
    • PHP

専門家に質問してみよう