• ベストアンサー

このプログラムの解説をお願いできないでしょうか?

以下の,意味を教えていただけると幸いです。 私は,HTMLからPerlに送り,再度記入者へ確認表示をさせたいと思っております。その中でこの部分が分かりません。お願いいたします。 for( $aIndex1 = 0 ; $aIndex1 < 20 ; $aIndex1++ ){ for( $aIndex0 = 0 ; $aIndex0 < 2 ; $aIndex0++ ){ $varName = "k" . $aIndex0 . $aIndex1 ; $anAns[ $aIndex0 ][ $aIndex1 ] = $input{ "$varName" }; $anAns[ $aIndex0 ][ $aIndex1 ] =~ s/\r\n//g ; } }

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

  • ベストアンサー
  • galluda
  • ベストアンサー率35% (440/1242)
回答No.4

がるです。 んっと…概ね二箇所の変更かと。 一つは前述の通りですので省略いたします。 もう一つは表示部分になるのですが。元々$anAnsをどのように処理していたかがもう一つ見えないのですが。 とりあえず「おもいっきりベタに定数で」片付けるなら、いっそ for($i = 0; $i > 19; $i ++) { } というループにして出力部分を出してしまってもよいのでは、と思います。 こんな感じでどうでしょうか?

nameworld123
質問者

お礼

貴重な時間を頂戴いたしまして,感謝申し上げます。なんとなく分かってきたような気がします。まだまだ完全作動には至りませんが,ご教示いただいた内容と,書籍を読みあさりながら格闘したいと思います。誠にお世話になりました。ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.3

がるです。んっと…ご指名いただいたようなので(笑 > 駅伝の選手名を登録したいのです。1区~37区までに,HTML側で,name="k00"~k36まで順番設に定しています。それをPerlに送り,再度browserで,2列の19行で表示したいのです。 > ご理解いただけたでしょうか? なるほどなるほど。…だとすると、ちと前述のコードでは厳しいような。 まず確認なのですが。k00~k36は連番ですよね? 連番であると仮定して。これを「2列の19行」にしてみます。 概ねこんな感じになろうかと思われます。 $anIdx[0] = 0; $anIdx[1] = 0; for( $i = 0; $i <= 36; $i ++) { # keyの作成 $varName = sprintf("k%02d", $i); #print "$varName \n"; # データの取得と改行コードの削除 $data = $input{ "$varName" }; $data ~= s/\r\n|\r|\n//g ; # 配列へのデータ挿入 # keyの元値が奇数か偶数かで左右に振り分けています if ($i & 1) { #print "1 : $anIdx[1] \n"; $anAns[1][$anIdx[1] ++] = $data; } else { #print "0 : $anIdx[0] \n"; $anAns[0][$anIdx[0] ++] = $data; } } これを記述されていたコードのかわりに入れていただければ、@anAnsという二次元配列(正確には「配列の配列」)に、必要な情報が格納されるかと思います。 > 可能で有れば,自作のHTMLとPerlの両方を御覧いただけると幸いです。 こちらに載せていただければ拝見も可能かと思いますので。もし差し支えなければ。

nameworld123
質問者

補足

2000字を越えてしまい,全部は載せられませんでした。 #!/usr/local/bin/perl $outFile = "c:\\Httpd\\ekiden\\meibo" ; # 選手名表示用 @aFifth=('01A','02B', '03A','04B', '05A','06B', '07A','08B', '09A','10B', '11A','12B', '13A','14B', '15A','16B', '17A','18B', '19A','20B', '21A','22B', '23A','24B', '25A','26B', '27A','28B', '29A','30B', '31A','32B', '33A','34B', '35A','36B', '37A'); printf( "Content-Type: text/html\n" ); printf( "\n" ); if( &ReadParse( *input ) ){ $userGrade = $input{ 'userGrade' }; $userClass = $input{ 'userClass' }; }else{ print "Parsing Error !!!\n" ; exit ; } for( $aIndex1 = 0 ; $aIndex1 < 20 ; $aIndex1++ ){ for( $aIndex0 = 0 ; $aIndex0 < 2 ; $aIndex0++ ){ $varName = "k" . $aIndex0 . $aIndex1 ; $anAns[ $aIndex0 ][ $aIndex1 ] = $input{ "$varName" }; $anAns[ $aIndex0 ][ $aIndex1 ] =~ s/\r\n//g ; } } if( opendir TEMPF, $outFile ){ close( TEMPF ); }else{ # サブディレクトリを作成する必要がある。 if( ( mkdir $outFile, 0777 ) == 0 ){ print "can't mkdir $outFile: $!\n" ; print "試験コードによるディレクトリ作成にエラー発生\n" ; exit ; # このプログラムを終了 } } # 学年を利用してサブディレクトリを作成 $outFile = $outFile . "\\" . $userGrade ; if( opendir TEMPF, $outFile ){ # 作成しようとしてるディレクトリは存在 close( TEMPF ); }else{ # サブディレクトリを作成する必要がある。 if( ( mkdir $outFile, 0777 ) == 0 ){ print "can't mkdir $outFile: $!\n" ; print "学年によるディレクトリ作成にエラー発生\n" ; exit ; # このプログラムを終了 } } <HTML> <HEAD> <TITLE> 駅伝区間選手登録受付通知 </TITLE> </HEAD> <BODY> <TABLE ALIGN="center" BORDER="1"> <TR> <TH BGCOLOR = "lime" ><FONT SIZE="2">学年</FONT></TH> <TH BGCOLOR = "lime" ><FONT SIZE="2">クラス</FONT></TH> </TR> <TR> <TD ALIGN="center"> $userGrade </TD> <TD ALIGN="center"> $userClass </TD> </TR> </TABLE> <HR><BR> <TABLE ALIGN="center" BORDER="1"> <CAPTION ALIGN="top"> <FONT SIZE="4" COLOR="blue"><B>駅伝区間選手登録受付結果</B></FONT> </CAPTION> EOF

全文を見る
すると、全ての回答が全文表示されます。
  • galluda
  • ベストアンサー率35% (440/1242)
回答No.2

がると申します。 直接的な解説は出来るのですが…全体を見ているわけではないので、このソースコードが「本質的に何をしたいのか」は憶測でしか語れませんのでそのあたりご了承ください。 直接的には。 まず、前提条件として、%inputという変数に、色々とデータが入ってるようです。 で、%inputという連想配列は、k00からk119までのkeyをもっているものと思われます(完全な連番ではないのですが)。 > $anAns[ $aIndex0 ][ $aIndex1 ] = $input{ "$varName" }; は、二次元配列の中に、対応する$input内のデータを格納しています。 で、その格納したデータに改行コードが入っている可能性があり、それを削除するために > $anAns[ $aIndex0 ][ $aIndex1 ] =~ s/\r\n//g ; という1文が入っています。 で。この実装の根幹部分(哲学)なのですが。 恐らく「HTMLからPerlに送り,再度記入者へ確認表示をさせたい」という文言から察するに。 入力のほうのHTMLに、k00とかk10とかk01とかk11とかいったnameが存在しているのではないでしょうか? で、それらのデータを出力したりチェックしたりするために、一端データを二次元配列に落とし込んでいる、のではないでしょうか? 以上、何かの参考にでもなれば幸いです。

nameworld123
質問者

補足

早速にありがとうございます。もう少しご協力をお願いします。 駅伝の選手名を登録したいのです。1区~37区までに,HTML側で,name="k00"~k36まで順番設に定しています。それをPerlに送り,再度browserで,2列の19行で表示したいのです。 ご理解いただけたでしょうか? 可能で有れば,自作のHTMLとPerlの両方を御覧いただけると幸いです。ご検討下さい。

全文を見る
すると、全ての回答が全文表示されます。
  • ralf124c
  • ベストアンサー率52% (232/446)
回答No.1

連想配列「%input : $input{'k00'~'k191'}」から値を2次元配列「$anAns[0-1][0-19]」に各々代入して、値の中に含まれる「DOS形式」の改行コードを削除してます。 蛇足かもしれませんが利用者のプラットフォームが異なると改行コードが変わりますので $anAns[ $aIndex0 ][ $aIndex1 ] =~ s/\r\n//g ;     ↓ $anAns[ $aIndex0 ][ $aIndex1 ] =~ s/\r\n|\r|\n//g ; としたほうが良いと思います。 \r\n は DOS(Windows) \r は Mac \n は UNIX です。

nameworld123
質問者

お礼

お忙しいところありがとうございました。書籍での理解には限界があり,プログラムの勉強をしたいです。お世話になりました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Perl このプログラムの解説をお願いします

    Perl初心者です。 簡易なタイマーのプログラムです。 (1)$s=shift||60; この部分の shift と || はどういった意味合いを持っているのでしょうか。 (2)for(1..$s) このfor構文の括弧内はどういった意味合いを持っているのでしょうか。 $s=shift||60; $|=1; for(1..$s){ sleep 1; print"$_\r" } print"\n"

    • ベストアンサー
    • Perl
  • プログラムの意味がわからなくて困っています

    こんにちは。以下のプログラムの意味がわからなくて困っています。分数q/p(p、qはともに正の整数)に関係するもので、3/13を入力したときの出力と、配列R()がどんな変化をしていくかを教えてください。 100 option base 0 110 dim A(1000) 120 dim R(999) 130 let N=1000 140 for I=0 to N-1 150 let R(I)=0 160 Next I 170 do 180 print"分母p="; 190 input P 200 if (P>N) then 210 print"分母は1000以下にしてください” 220 end if 230 loop while(P>N) 240 print"分子q="; 250 input Q 260 let A(0)=int(Q/P) 270 let Q=mod(Q,P) 280 let K=0 290 Do 300 let K=K+1 310 let R(Q)=K 320 let Q=Q*10 330 let A(K)=int(Q/P) 340 let Q=mod(Q,P) 350 loop while (R(Q)=0) 360 print A(0);"."; 370 for I=1 to R(Q)-1 380 print A(I); 390 next I 400 if (R(Q)<K) or (A(K)<>0) then 410 print "{"; 420 for I=R(Q) to K 430 print A(I); 440 next I 450 print"}"; 460 end if 470 end 100から160までで配列Aを1000個、配列Rを999個準備し、配列Rの中身を0にしている。 170から230で分母Pに13を入れ分母が1000以下になることを確認している。1000以上であれば、1000以下になるまでループ内を繰り返す。 240以下で分子を入れているようですが、ここからよくわからなくなってしまいました。 よろしくお願いします。  

  • プログラム(BASIC) 教えてください

    (1) INPUT文で入力した整数 k に対し, 3, 5, 7, 9 のいずれかの値をランダムに等確率で発生し,改行せず横に続けて k個 表示させるプログラム (2)初項 a ,公差 r ,長さ n の等差数列 a, a+r, a+2r, ..., a+(n-1)r のいずれかの値を等確率で発生させるためには,乱数をどのような式で作れば良いか? INPUT文で与えられた a, r, n, k に対して,この等差数列のいずれかの値をランダムに k 個表示させるプログラム (1)は0,2,4,6を考えてから+3すればいいと思うのですがランダムに0,2,4,6を表示するプログラムの仕方が分かりません。 10 INPUT k 20 FOR L=1 TO k 30 RANDOMIZE 40 PRINT INT(   )+3; 50 NEXT L 60 END 解説があるとありがたいです。

  • htmlファイルの改行について

    複数ある html ページから、改行部分( <BR> ではなくて )、を自動的に削除して再び保存する、というプログラムを自作しているのですが、\r\n, \r, \n に当てはまらない改行コード? があるみたいで、完全に取りきれないのです。 $input =~ s/\n\r//g; $input =~ s/\n//g; $input =~ s/\r//g; もしくは、 $input =~ s/\x0D\x0A|\x0D|\x0A//g; という具合にしているのですが、予想では、数行にわたるhtml タグから全ての改行が取り除かれ、一行にまとまると いうイメージがあるですが、ところどころ改行が残ります。何がいけないのでしょうか・・・

    • ベストアンサー
    • Perl
  • 巡回群について

    「Gを位数nの巡回群とする.このとき,Gの部分群の位数はnの約数で,各約数に対してただ一つ存在する.」 この証明でいくつか分からなかったので教えてください. (以下証明) G=<g>とし,m|nであるとする. ここでn/m=cとおくと,<g^c>は位数mの巡回部分群になる. また,これと異なる位数mの巡回部分群Sが存在すると仮定する. g^k∈S (kはこれを満たす最小の正整数)とすると,剰余の定理から n=qk+r (0<q∈Z,0≦r<k) となるq,rが存在する.このとき, g^r=g^(n-qk)=g^n(g^(-k))^q∈S で,kの最小性よりr=0を得る. よってn=qkとなり,Sの位数はqとなる.-(1) したがってm=qとなり,S=<g^c>.-(2) 以上より,nの約数に対して,ただひとつの巡回部分群が存在する. (証明終) この証明の最後の, (1):Sの位数はqとなる (2):S=<g^c> の部分がわかりませんでした. (1)について (g^k)^q=g^qk=g^n=e となりますが,これより「Sの位数はq」ということですか? (2)については包含関係を示しているのでしょうか? その辺がよくわかりませんでした. 長文申し訳ありませんがよろしくお願いいたします.

  • 成績処理のプログラムについて・・・

    成績処理のプログラムについて・・・ 先日、http://okwave.jp/qa/q5911162.htmlにて質問させていただいたのですが、今回は平均点の計算及び出力について教えていただければと思います。 #include "stdafx.h" void input(void); void calc(void); void edit(void); int gakusei=10,kamoku=5; /*学生数、科目数*/ char kamokumei[5][40]; /*科目名*/ char shimei[10][40]; /*氏名*/ int tennsuu[10][5]; /*点数*/ float heikin[10]; /*平均点*/ void main() { input(); calc (); edit (); } void input(void) /*データ入力(infile.d.txtから読み込む)*/ { FILE *fp; int m,n,k; fp=fopen("infile.d.txt","r"); if(fp==NULL) { printf("infile.d.txtが開けません\n"); } fscanf(fp,"%d %d\n",&gakusei,&kamoku); for(m=0; m<kamoku; m++) { fscanf(fp,"%s",kamokumei[m]); } for(n=0; n<gakusei; n++) { fscanf(fp,"%s",shimei[n]); } fscanf(fp,"%s %s・・・%s",&tennsuu[0][0],&tennsuu[1][0],・・・ ,&tennsuu[9][0]); ・・・ fscanf(fp,"%s %s・・・%s",&tennsuu[0][4],&tennsuu[1][4],・・・,&tennsuu[9][4]); fclose(fp); } void calc(void) /*各学生の平均点を計算、平均点の優秀者(80点以上)及び不合格者(60点未満)を摘出*/ { int n,k; float sum=0; for(n=0; n<gakusei; n++) { for(k=0; k<kamoku; k++) { sum+=(float)tennsuu[n][k]; } heikin[n]=sum/kamoku; } } void edit(void) /*平均点、優秀者及び不合格者の氏名を付加した成績表を出力(outfile.d.txtに書き込み)*/ { FILE *seiseki; int m,n,k; seiseki=fopen("outfile.d.txt","w"); fprintf(seiseki,"氏名"); for(m=0; m<kamoku; m++) { fprintf(seiseki," %s",kamokumei[m]); } fprintf(seiseki," 平均\n"); fprintf(seiseki,"%s %s %s・・・%s %d\n",shimei[0],&tennsuu[0][0],&tennsuu[1][0],・・・,&tennsuu[4][0],heikin[0]); ・・・ fprintf(seiseki,"%s %s %s・・・%s %d\n",shimei[9],&tennsuu[5][4],&tennsuu[6][4],・・・,&tennsuu[9][4],heikin[9]); fprintf(seiseki,"\n"); fprintf(seiseki,"平均点優秀者\n"); fprintf(seiseki,"平均点不合格者"); fclose(seiseki); } 上記のプログラムを"outfile.d.txt"に出力してみると、平均点が82となる部分が-1610612736、74となる部分が-1610612736と表示されたりしてしまいます。 平均点の計算部分が違うのか、出力の仕方が悪いのか色々試してみたのですが思うようにできません。 どのように直せばよいのでしょうか? よろしくお願いします。 また、平均点の優秀者・不合格者の摘出方法についてもどのようにすれば良いのか教えて頂けるとありがたいです。

  • ガウスの消去法のプログラム

    ガウスの消去法(部分ピボット選択)のプログラムを組んでみたつもりなのですが上手くいきません。 間違いだらけだと思いますがどうかアドバイスをして頂けませんでしょうか? #include <stdio.h> double main(void){ int i,j,k,N,M,m; double A[N+1][N+1][N+1],B[j],S,X[N+1]; printf("次数の入力。\n"); scanf("%d",&N); for(k=1;k<=N;k++){ for(i=1;i<=N;i++){ for(j=1;j<=N+1;j++){ A[k][i][j]=0; } } } for(i=1;i<=N;i++){ for(j=1;j<=N+1;j++){ printf("係数の入力.\n A[1][%d][%d]?\n",i,j); scanf("%f",&A[1][i][j]); } } for(k=2;k<=N;k++){ if(A[k-1][k-1][k-1]=0){ for(M=k;M<=N;M++){ if(A[k-1][M][k-1]!=0){ for(j=k-1;j<=N+1;j++){ B[j]=A[k-1][k-1][j]; A[k-1][k-1][j]=A[k-1][M][j]; A[k-1][M][j]=B[j]; } goto abc; } else {printf("解は無い\n");} } } abc: for(i=k;i<=N;i++){ for(j=k;j<=N+1;j++){ A[k][i][j]=A[k-1][i][j]-(A[k-1][i][k-1]/A[k-1][k-1][k-1])*A[k-1][k-1][j]; } } X[N]=A[N][N][N+1]/A[N][N][N]; printf("解X(N)は %f 。\n",X[N]); for(k=N-1;k>=1;k--){ S=0; for(m=N;m>=k+1;m--){ S+=A[k][k][m]*X[m]; } X[k]=(A[k][k][N+1]-S)/A[k][k][k]; printf("解X(%d)は %f 。\n",k,X[k]);} } }

  • プログラムについて(UNIX)

    以下のプログラムを部分的で結構ですので 解説していただけないでしょうか? 打ち込んだ数字を10進法に変換して、 その後どうなっているのかがよく分かりません。 よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<math.h> #define N 127 #define M 121 #define LENGTH 45539 int C[N] ; int d[LENGTH/N]; int b[LENGTH/N]; float r[LENGTH]; char message[LENGTH/N/7]; int PNread(int); int PXread(void); int main() { int i, m; /* Insert the process to input the user No. m here. */ printf("Input the user No. : "); scanf("%d", &m); if (m < 0 || m > M) { printf("You input a wrong user No.\n"); exit(-1); } printf("\nThe user No. m is %d. \n", m); /* Read the spread code for user No. m from data file */ if(PNread(m) == -1) exit(-1); /* Display the spread code. */ /* Here is an example to display the first 10 numbers */ if(PXread()== -1) exit(-1); int t,k; float hatD[LENGTH/N]; for(t=0; t < LENGTH/N; t++){ hatD[t]=0; for(k = t*N; k < (t+1)*N; k++) hatD[t]+= ((float)r[k]*C[k%N])/((float)N); d[t] = (hatD[t] >= 0)?1:-1; /*?はif文の省略形である*/ } for(t = 0; t < LENGTH/N; t++) b[t] = (d[t] >= 0) ? 0 : 1; /* 文字に変換する */ for(i = 0; i < LENGTH/N; i += 7) message[i/7] = b[i]*64 + b[i+1]*32 + b[i+2]*16 + b[i+3]*8 + b[i+4]*4 + b[i+5]*2 + b[i+6]; /* メッセージの表示 */ printf("Message:\n%s\n", message); return 0; } /* Function of spread code reading */ int PNread(int m) { FILE *in; /* Verify the data file */ if ((in = fopen("PN7.dat", "r"))== NULL) { /* Error message */ printf("Error: Cannot find the data file. \n"); return -1; } if(m>1) /* Set the file pointer to the m-th user's spread code */ fseek(in,(m-1)*N*sizeof(int),SEEK_SET); /* Read the spread code to array C */ fread(C,sizeof(int),N,in); fclose(in); return 1; } int PXread(void) { FILE *in; int count; float rtemp; if((in = fopen("Rx7_51.dat", "r"))== NULL) { printf("Error; Cannot find the date file. \n"); return -1; } for(count = 0; count < LENGTH; count++){ fscanf(in, "%f", &rtemp); r[count] = rtemp; } fclose(in); return 1; }

  • (プログラムがあるため長文です)次の2つの違いは?

    C言語(VisualStudio.net2003)で組み合わせに関するプログラムを作成したのですが、(1)の式で、プログラムを実行させると、違う結果が出てしまい、(2)の式で実行させると、正しい結果が出ます。 (1)(コピーして、確認(実行)してみてください) #include <stdio.h> int main ( void ) { int n,r,k; int a=1; printf("n=?");scanf("%d",&n); printf("r=?");scanf("%d",&r); for ( k=1 ; k<=r ; k++){ a *= (n-k+1)/k; printf("a%d=%d\n",k,a); } return 0; } (2)a *= (n-k+1)/k; の部分を a = a*(n-k+1)/k; に変更する。 a *= (n-k+1)/k;という式が、a = a*(n-k+1)/k;ということを意味しているので、どちらでも正しい結果がでる気がするのですが、なぜ(1)では正しく結果が表示されないのでしょうか?教えてください。 また、(1)のような *= をつかってプログラムを組みたいとき、a *= (n-k+1)/k; をどのように変更すればよいのでしょうか?

  • sinのプログラム

    #include<stdio.h> #include<math.h> #define NMAX 100 main(){ float eps,x,t,s; int n; printf("Taylor series\n"); scanf("%g",&eps); printf("eps=%g\n",&x); for(;scanf("%g",&x)!=EOF;){ printf("\nx=%g\n n\tt\t\ts\n",x); t=s=1; for(n=1;n<NMAX;n++){ t*=X/n; s+=t; printf("%2d %15.6e %15.6e\n",n,t,s); if(fabs(t)<eps) break; } if(n>=NMAX) printf("---not converged ---\n); printf("exp(%g)=%g\tn=%d\n",x,s,n); } return(0); } これはeの級数展開をもとめるプログラムなのでが、これをsinの級数展開のプログラムに改造しろという問題があります。 sinのn乗の項を求めてeの部分と置き換えてやってみたのですができません。 どなたかわかる方がいましたら、教えてください。