• ベストアンサー

fgetsで取り込んだ文字をexplodeで配列にしたい

こんにちは PHPの勉強を始めたばかりです。 あまり関数もたくさん知りませんが、今のところ覚えたもので、外部ファイル(TXTファイル)から文字列を引っ張り出して、スケジュール表を生成するPHPを作りたいと考えています。 カンマで区切られた文字列を格納したdata.txtというファイルがあります。 内容は 開催月,開催日,時間帯,定員,応募締切月,応募締切日 で、データとしては 6,10,AM,12,5,30 という感じで格納されています。 以下まで作ってみました。 <?php //data.txtの読み込み $rData = fopen('data.txt','r');//data.txtを読み込み専用で開き、変数rDataで扱えるようにする $i = 0; while(!feof($rData)){//eof(ファイルの終端)でない限り続ける繰り返し処理 $DataLine = fgets($rData);//1行を取り出し、変数DataLineに格納する $DataLine.$i = explode(",",$DataLine);//DataLineに格納した文字列をカンマで分割してDataLine0やDataLine1などの配列に格納 $i ++; } fclose($rData);//開いていたファイルを閉じる ?> <html> <head> <title></title> </head> <body> <?php echo $DataLine0[0]; ?> </body> </html> data.txtの1行目には、 6,10,AM,12,5,30 という文字列が入っています。 ですので、自分としてはこの処理で1行目のはじめの文字である「6」が表示されると思い込んでいたのですが、できませんでした。 画面には何も表示されません。特にエラーも表示されませんでした。 この処理の方法は何か間違っているのでしょうか。 お分かりになる方、いらっしゃいましたら、お力添えいただければ幸いです。 よろしくお願いいたします。

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

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

  • ベストアンサー
  • SeafooD3
  • ベストアンサー率75% (6/8)
回答No.2

こんにちは。 まずは修正版のコードを記述します。 $rData = fopen('data.txt','r');//data.txtを読み込み専用で開き、変数rDataで扱えるようにする $i = 0; while(!feof($rData)){//eof(ファイルの終端)でない限り続ける繰り返し処理 $DataLine = fgets($rData);//1行を取り出し、変数DataLineに格納する $DataPars[$i] = explode(",", $DataLine); $i++; } それから書き出しのところ。 <?php echo $DataPars[0][1]; ?> 簡単に説明しますが、 $DataLine.$iのコードの意味はくっつけて表示という使い方はしますが、変数名として合体させる力はありません。 $DataLine.$i = explode(",",$DataLine); //NG ですので、配列として、 $DataPars[$i] = explode(",", $DataLine); としてあげることで、配列名と番号のセットされたものに、explodeで作られた配列が入ります。 配列の中に、さらに配列を入れてあげます。 これを1回のセットとしてループしてあげれば、 $DataPars[0] = 1行目の配列 $DataPars[1] = 2行目の配列 というように続きます。 そして、$DataPars[0]この配列の中にある配列を呼び出すには、 $DataPars[0][0] = 1行目の配列の0番目のカラムというようにしてあげましょう。

hoso1974
質問者

お礼

ご回答ありがとうございます。 教えていただいた方法でできました! すごい! 配列の中に、配列が作れるんですね! まだまだ勉強不足です。 でも、教えていただいたことで、また少し壁を越えることができました。 ありがとうございました!!!

その他の回答 (1)

回答No.1

> $DataLine.$i = explode(",",$DataLine);//DataLineに格納した文字列をカンマで分割してDataLine0やDataLine1などの配列に格納 ここの考え方が間違っています。 この書き方だとexplode の結果は $i という変数に格納されます。 決して、 Dataline に $iの内容(まあexplodeでぶっ壊されているのは置いといて) を連結した名前の新しい変数(DataLine1とか)に代入されるわけではありません。 可変変数というものでお望みのことをできなくもありませんが、 素直に配列を使うことをオススメします。

hoso1974
質問者

お礼

早速のご回答ありがとうございます。 教えていただいたとおり、「$DataLine.$i」という表現を「$DataLine2」に変更して「echo $DataLine2[0]」とすることで、最終行の先頭データを表示することができました。 となれば、この方法では、たとえばdata.txtにレコードが10件入っていたとしても、各レコードを別々の変数に入れておくことは難しいでしょうか。 別々に格納しておくことができれば、後々、HTML側への出力として <?php echo $DataLine0[0].'月'.$DataLine0[1].'日'.$DataLine0[2].…; echo $DataLine1[0].'月'.$DataLine1[1].'日'.$DataLine1[2].…; echo $DataLine2[0].'月'.$DataLine2[1].'日'.$DataLine2[2].…; ・ ・ ?> といったようなことが可能になるかな?と思い、自分なりに作ってみたのがはじめに記載したものでした。 もう少し、試行錯誤してみます。 ありがとうございました。

関連するQ&A

  • 文字列の動的確保とポインタ配列について

    C言語についての質問です。 現在、キーボードから文字列を読み込みファイルに保存するプログラムを作成しています。 プログラムの条件は、以下の通りです。 1: キーボードから英数字(最長でMAX_LEN(1000)-1文字)を入力して文字列(文字配列)dataに格納後、画面に表示する。 2: 入力された文字列と同じ長さの文字列を格納する領域を動的に確保し、文字列dataをその領域に コピーする。なお、必要な文字配列の長さは文字列の長さ+1バイトである。 3: 文字列endが入力されるか、入力された文字列がNUM_STRING(10)個になるまで1~2の処理を繰り返す 4: 各文字列へのポインタを格納する(char *)型ポインタの配列str_p(サイズ:NUM_STRING)を定義して利用する。 5:1~2の処理が終了した後で、メモリに格納されたすべての文字列をファイルに出力する。ファイル名はoutput.txtとし、最初の行に文字列の個数を、次の行以降に入力された順番と「逆の順番」で文字 列を出力すること。 実行例 input ->st22 st22 input->st1 st1 end ファイルの中身 2 st1 st22 現在完成しているプログラムは以下の通りです。 #include<stdio.h> #include<string.h> #include <stdilb.h> #define NUM_STRING 10 #define MAX_LEN 1000 int main (void) { int n, i; char data[MAX_LEN] = {}; char *str_p[NUM_STRING]; FILE *fp; do { printf("input->"); scanf("%s", data); if (strcmp(data, "end") == 0) { break; } else { printf("%s\n", data); n++ 2の処理 } while(n <= NUM_STRING); if ((fp = fopen("output.txt", "w")) == NULL) { fprintf(stdout, "File open error\n"); } fprintf(fp, "%d\n", n); for (i = n-1; i>0; i--) fprintf(fp, "5s\n", str_p[i]); fclose (fp); return 0; } 特に動的確保のところがよく分かりません。 回答よろしくお願いします。       

  • ファイルから読み込んで配列へ

    PerlでCGIスクリプト(掲示板もどき)を作成しています。 配列の操作がうまくいかず、ご教授頂きたいと思います。 <やりたい事> 1.ブラウザ上のフォームからの入力を、カンマ区切りでテキストファイルに追記して保存。 2.そのテキストの一部を使ってHTMLで表を作る。 <実際の作業> 1.フォームからのデータはcgi-lib.plで連想配列として受け取り、unshiftでテキストファイルへ追記する。 &ReadParse; #フォームからデータを受け取る $o=$in{'name'}; $p=$in{'mail'}; $q=$in{'title'}; $r=$in{'comment'}; open(IN,"xxx.txt"); @tmp1=<IN>; close(IN); #1件1行として新規データを追加する unshift (@tmp1,"$oo" , "," , "$pp" , "," , "$qq" , "," , "$rr","\n"); open(OUT,">xxx.txt"); print OUT @tmp1; close(OUT); 2.xxx.txtのデータを読み込んで、1列目(name)と3列目(title)だけを使った表を作る。 データを読み込む時点でつまづき、先に進めません。 <テキストファイルの例> 1行目:a,b,c,d 2行目:e,f,g,h 3行目:i,j,k,l 以下同様 <症状> print @tmp1;とすると、a~lの全てのデータが表示される。 $tmp1[0];とすると、(a)のみ表示される。 $tmp1[1];とすると、カンマ(,)が表示される。 $tmp1[2];とすると、(b)が表示される。 <質問> 一つの行(配列)に対して2回繰り返す処理(nameとtitle)と、行単位で繰り返す処理(1行目、2行目…)を合わせればいいのだろうと思っていますが、どうすればいいのかわかりません。 気分的には↓こんな感じです。 foreach { "行の処理" foreach { "列の処理" } } そもそも、区切り文字であるカンマが、配列に格納されている時点で失敗しているのかな?とも思っています。 宜しくお願いします。 なお、不足している情報がありましたら補足いたします。

    • ベストアンサー
    • Perl
  • fgetsの使い方

    C言語を今日から始めたじいさんです。 宜しくお願い致します。 メモ帳を使って3行ほどの文字列を入力して、text.txtファイルに保存します。 この文字列を読み込んで、1行ずつ印刷しようとしていますが fgetsでtxtファイルの終了条件がわかりません。 while(fgets(row , sizeof( row ) , fp) != NULL){ printf("%s\n , row); } fclose( fp ); return 0; のようにしているのですが、3行印字処理をして異常終了してしまいます。 本に出ている例をそのまま実行しているのですが、うまくいきません。 txtファイルをダンプしてみると各行の後ろに0d 0aたぶんCR,LFが入っていてNULL=00(?)はありません。テキストファイルの作り方に問題があるのでしょうか? それともfgetsの使い方に誤りがあるのでしょうか?

  • AWKの配列内データの処理について

    AWKを使用して入力ファイルの1行内の単語に対して条件チェックするには for( i=1 ; i<= NF i++ ){    if( $I == chek_word )       処理 } とすればできるのはわかるのですが、 一旦、配列の中に格納した文字列に対して上記の処理と同様の処理をするにはどのようにすればいいのでしょうか? 例えば data_line[$1] = $0; として配列data_lineに格納した1行そのままのデータに対して1番上の行全体にわたる単語の条件チェック をおこないたいのですが、どのようにすればいいのかよくわかりません。 どなたかご存知の方アドバイスをお願いします。

  • 2次元配列から1次元配列へのデータ読み込み方法をお尋ねします。

    いつもお世話になります。 readtest.csvというCSVファイルを作り、データを次のように入れています。 a,apple,301,23 b,orange,518,47 c,grape,278,19 d,banana,189,36 この3列目のデータを取り出して1次元配列に入れるため、DBtest.phpを次のように書きました。 01: <?php 02: $Data=file("../readtest.txt"); 03: for ( $i = 0; $i < sizeof( $Data ); $i++ ) { 04: $line=explode(",",$Data[$i]); 05: echo $line[2]; // 301518278189 06: // $xdata=implode(",", $line[2]); 07: } 08: ?> この実行結果は、「301518278189」となります。なぜコンマが入らないのでしょうか? 5行目をコメントアウトして6行目を生かして実行すると、 Warning: implode() [function.implode]: Bad arguments. in C:\Program Files\Apache Group\Apache2\htdocs\DBtest.php on line 6 となります。 3列目のデータを抜き出して配列を作るにはどのようにすれば良いでしょうか? よろしくご教示頂ければ幸いです。

    • ベストアンサー
    • PHP
  • PHPで、○番目のカンマの文字を呼び出す方法

    0,123,45,678,999 など、カンマ区切りの情報がある data.txt というファイルがあり、 別のPHPファイルにdata.txtの内容を書き出したい場合、 <?php echo file_get_contents("data.txt"); ?> と書くと全部表示されてしまいます。 data.txtの1行目で、2番目と3番目のカンマの間の数字(上の例ですと123)を書き出すには、どのように書いたらよいか、お分かりになる方教えて頂けませんでしょうか。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • String配列を扱うアルゴリズムについて

    よりパフォーマンスの良いアルゴリズムが、 ございましたらご教示下さい。 数レコード分のDBテーブルデータが格納されたString[][]型が存在するとします。 配列の要素は、String[行(フィールド)][列(カラム)]です。 ここで、全レコード中の列ごとの最大文字列長を int[]型に取得したいと思います。 そうした場合、自作した下記の処理よりも、 よいパフォーマンスを得られるアルゴリズムがございましたら、 ご教示願いたいと思います。 ※処理前提条件 ●String[][]型変数に、過不足無くテーブルデータが格納済みであるとします。 ●配列の第一(行)・第二(列)要素の最大値は取得済みであるとします。 ////////////// // 変数定義 // ////////////// String[][] tableData; ← テーブルデータ格納済み(過不足はありません) int 行数 = 全行数(取得済み); int 列数 = 全列数(取得済み); //列毎の最長文字列値を格納する。 int[] maxLen = new int[列数]; ////////// // 処理 // ////////// //列の個数分、処理を繰り返す for(int i = 0; i < 列数; i++) {   //行の個数分、処理を繰り返す   for(int j = 0; j < 行数; j++) {     //NULLを回避する     if(tableData[i][j] != null) {       //int配列に格納済みの数値より大きければ、改めて格納する       if(maxLen[i] < tableData[i][j].length()) {         maxLen[i] = tableData[i][j].length();       }     }   } } 以上です、どなかお知恵をお貸し頂けませんか。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • 文字列を格納する配列を、動的なメモリ確保で処理したい

    文字数が一定でない文字列の一覧を、配列に格納したいと思っています。 "AAA" "BBBBB" "CC" このような文字列を配列に格納するのに普通にやるなら char test[3][24]; for(i=0;i<3;i++){ strcpy(test[i],file[i]); } (便宜上、file[0]には、"AAA",file[1]には"BBBBB"が格納されてるとします) こうやると、test[3][24]の24バイトとか余計に確保した分が無駄になるので、 必要な文字列の長さだけ配列を確保したいと考えています。 で、 char *test[3]; for(i=0;i<3;i++){ //sizeには、各文字列のサイズが格納してあります。ここではその部分省略しますが test[i]= (char*)malloc(size); strcpy(test[i],file[i]); } とやれば (イメージで) test[0]= "AAA" test[1]= "BBBBB" test[2]= "CC" となると思ったのですが、うまく処理されませんでした。 このような処理をさせたい場合根本的に違うのでしょうか。 わかりにくい説明ですが、どなたかご存知の方よろしくお願いします

  • C言語 文字列格納

    テキストファイルから整数データ又は文字列を読み込んで配列に格納する動作についての質問です。 テキストファイルが1行区切りの整数型なら1次元配列で for(i = 0; i < maxSize; i++) { fscanf(fp,"%d", &data[i]); } テキストファイルが1行区切りの文字列なら2次元配列で for(i = 0; i < MAXSIZE; i++) { if (fscanf(fp,"%s", &data[i][300]) == EOF) break; } for(j = 0; j < i; j++) printf("%s\n", data[j]); みたいな具合に格納できたんですが、 テキストファイルが1行区切りのデータではなく、空白文字区切りの文字データだった場合、それぞれどのようにして配列に格納すればいいかがわかりません。 イメージとしては、1文字目から見ていって空白が出ればそこで切って格納していくというかんじなのですが・・・ 質問の内容がわかりにくいかもしれませんが、是非教えてください。お願いします。

  • 一行データから構造体・配列への格納処理について

    初めて投稿します。 ▲実現したい処理内容 1)ファイルを読み込む。 2)読み込んだデータを独自定義した構造体データ配列に格納する。 3)格納した構造体データをパラメータに引き渡す。 ▲ファイルデータについて ・連続した文字列(カンマなどの区切りはなし) ・一行のみ --------10--------20--------30 abcdefgあいうえ123456789012 ▲条件 構造体を使う以外になし ▲状況 今のところ、自分でわかっているのは >2)読み込んだデータを独自定義した構造体データ配列に格納する。 の処理で、 ************************************************************** <最終的に渡すパラメータの型やサイズは決まっているので、 決まった文字サイズでデータから文字を切り出し、操作して パラメータへ渡す>処理で実現できる ************************************************************** なんですが、 構造体を使うロジックで実現しようとし、 関数は freadが適当であるということをアドバイスされましたが、 リファレンスの内容が理解できず困っています。 ファイルを開いて、 char buffer[256]; fgets(buffer, sizeof(buffer), fp); でbufferに文字列を格納する部分までは実現&理解できております。 ご教示いただければ幸いです。 よろしくお願い致します。

専門家に質問してみよう