
更新記録CGI(perl)を利用して、それを改造したいと思っています。
記事は1つだけ表示して、記事下に「←次へ」「前へ→」のようなリンクを作って前後に移動したいです。
素人考えで以下のようにしました。
$no =5; (現在の記事NO。数字が入ります)
$new_no = $no--;
$old_no = $no++;
print "<a href=\"news.cgi?vno=$new_no\">「←次へ」</a>\n";
print "<a href=\"news.cgi?vno=$old_no\">「前へ→」</a>\n";
しかしこれだと、2つの問題が発生します。
1.最新記事・最古の記事の次または前ページが存在しないのに行ってしまう。
2.何らかの理由で記事を消した場合でもそこに行ってしまう。
この2点を回避するにはどうしたら良いでしょうか?
$no =5;
open(IN,"$logfile") || &error("Open Error : $logfile");
while (<IN>) {
($no,$year1,$month1,$day1,$name,$tail1,$W1,$H1,$item1,$item2,$item3,$item4,$item5,$host) = split(/<>/);
<<<--- どうにかして、この記事の次記事があるかを判別する --->>>
if($new_no){
print "<a href=\"news.cgi?vno=$new_no\">「←次へ」</a>\n";
}else{
print "<font color=#aaaaaa>「←次へ」</font>\n";
}
<<<--- どうにかして、この記事の前記事があるかを判別する --->>>
if($old_no){
print "<a href=\"news.cgi?vno=$old_no\">「前へ→」</a>\n";
}else{
print "<font color=#aaaaaa>「前へ→」</font>\n";
}
このようにしたいのですが、方法を教えてください。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
> これをしたいのですが、どのように記述したら良いかがわからないほどの初心者です
それなら、まずは、このやり方に見当がつくくらいの勉強をしてからの方がよいのでは?
・テキストファイルを全部リストに入れる方法
・リストの並び換えの方法(sort関数のちょっと高度な使い方)
などは、初級の入門書にも載っていると思います。
※ 他にも
「3行だけ記録して、真ん中が該当行だったら前後の記事番号を使う」
「注目記事番号未満のうちの最大値と、注目記事番号超のうちの最小値を求める」
等の手法もあります。
それから、++ / -- はちゃんと理解してください。
単に「1減らした数」ということにはなりません。
変数の前に書いたときと後に書いたときとの違いも重要です。
理解できていないのなら、使わない方がいいくらいです。
$new_no=$no++;#新しい記事だから現記事より+1
とありますが、 後に置いた場合の ++ は
・まず、元の値を使用する
・使った後でその変数自体を+1する
という効果があります。つまり、この文は
{
$new_no=$no;
$no=$no + 1 ;
}
とほぼ同じことになります。同様に
$old_no=$no--;#古い記事だから現記事より-1
は
{
$old_no=$no ;
$no = $no - 1 ;
}
です。
では、最初に$no=5として
$new_no=$no; #=> $new_no = ?
$no=$no + 1 ; #=> $no = ?
$old_no=$no ; #=> $old_no = ?
$no = $no - 1 ; #=> $no =?
としたら、それぞれどうなりますか?
上の?をそれぞれ埋めてみてください。
No.3
- 回答日時:
> ログファイル開く→現ページを確認→それに+1と-1した数字を作る→whileでヒットしたところを表示
考えていけば、いくらでも方法はありますが、とりあえずは、その方針でいいのでは?
あとは、ちょっとしたアイディアだけです。
例えば:
○「数字を作る」のではなくて、-1番目、+1番目を探す。
全行を記事番号順にソートして、 @l に保存
$l[$i] が$noの記事なら、 $l[$i-1] と $l[$i+1]が目的の「前後の記事」。
$i==0なら「前の記事」は無いし、$i+1と@lの長さを比較すれば「後の記事」が存在するかどうか判定できる
他にも:
前の記事番号 = $noより小さい記事番号の最大値
後の記事番号 = $noより大きな記事番号の最小値
であることに注目する
それ以前の問題として、no++/no--では期待する番号になっていない、というのは、既に指摘のある通りです。
この回答への補足
返答ありがとうございます。
>全行を記事番号順にソートして、 @l に保存
>$l[$i] が$noの記事なら、 $l[$i-1] と $l[$i+1]が目的の「前後の記事」。
これです!これをしたいのですが、どのように記述したら良いかがわからないほどの初心者です。
出来れば具体的にどうしたら良いかを教えていただけるととてもうれしいです!
No.2
- 回答日時:
「プログラムがあるからデータ構造もわかるだろ」ってのは, 質問としては乱暴だなぁ. 現実的な問題として
どうもきちんとデータか読めないと思ったら, 実はプログラムが間違ってました
ってこともあるわけなので, データ構造はデータ構造として書いておくべきだと思うよ.
さておき, 大事なことを聞き忘れていました.
・「削除」すると, データとしてはどうなるんですか? 当該行が消えるのか, それともどこかに「削除したよ」って情報が記録されるのか, あるいはそのどちらでもない別の方法で管理する?
・(こっちはさほど重要じゃないけど) 順番はどうなっていますか?
いずれにしても方向性としては「適切なデータ構造を作る」ことになるわけだけど, その「適切なデータ構造」が条件によって変化する可能性はある.
あと余談だけど, $vno が 5 のとき
$new_no = $vno--;
$old_no = $vno++;
によって $vno, $new_no, $old_no の値がどうなるか答えられますか?
この回答への補足
返答ありがとうございます。
>データ構造はデータ構造として書いておくべきだと思うよ.
すみません。そういう事以前に、何をどう記入したら良いかさえ分かっていない初心者なので、あのような書き込みになっていまいました。
細かく指示をもらえるととてもありがたいです。
>「削除」すると, データとしてはどうなるんですか?
その行が消えます。
ログに、
5<>2014<>1<>1<>新着題名5<>~
4<>2014<>1<>1<>新着題名4<>~
3<>2014<>1<>1<>新着題名3<>~
2<>2014<>1<>1<>新着題名2<>~
1<>2014<>1<>1<>新着題名1<>~
とあって、4番目の記事を削除すると
5<>2014<>1<>1<>新着題名5<>~
3<>2014<>1<>1<>新着題名3<>~
2<>2014<>1<>1<>新着題名2<>~
1<>2014<>1<>1<>新着題名1<>~
となります。
こういうログで、該当する記事を表示させたい場合、「~news.cgi?vno=5」のようにして、内部では、
while (<IN>) { ($no,$year1,$month1,$day1,$name,$tail1,$W1,$H1,$item1,$item2,$item3,$item4,$item5,$host) = split(/<>/);
if ($in{'vno'} == $no) {
print"$name<br>~\n";
}
}
で記事を探します。
この方式だと、$noに1をプラスマイナスした場合、消された記事に行ってしまうことになりますよね…
>あと余談だけど, $vno が 5 のとき
すみません、これも書き間違えですよね
while (<IN>) { ($no,$year1,$month1,$day1,$name,$tail1,$W1,$H1,$item1,$item2,$item3,$item4,$item5,$host) = split(/<>/);
if ($in{'vno'} == $no) {
print"~\n";
$new_no=$no++;#新しい記事だから現記事より+1
$old_no=$no--;#古い記事だから現記事より-1
#↑この位置なら$in{'vno'}は使う必要なしですよね?
}
}
で、
$vnoを5としたら
$new_noは6、$old_noは4と思ってますが、間違ってないでしょうか?
今これを記入しながら少し考えたのですが、該当する記事番号が無ければさらに+1(-1)すると言うのはどうでしょう?
次・前のリンクをそれぞれ
~news.cgi?vno=$new_no&move=new
~news.cgi?vno=$old_no&move=old
とし、
while (<IN>) { ($no,$year1,$month1,$day1,$name,$tail1,$W1,$H1,$item1,$item2,$item3,$item4,$item5,$host) = split(/<>/);
if ($in{'vno'} == $no) {
print"~\n";
$new_no=$no++;#新しい記事だから現記事より+1
$old_no=$no--;#古い記事だから現記事より-1
#↑この位置なら$in{'vno'}は使う必要なしですよね?
#この位置に前後へのリンク
}else{#該当記事が無ければ
if($in{'move'} eq $new){
$vno++;
&view; #この表示をするサブルーチンに戻る
exit;
}
if($in{'move'} eq $old){
$vno--;
&view; #この表示をするサブルーチンに戻る
exit;
}
}
…
すごく回りくどいことをしているようにも思いますが…
でも、これだと、最初の記事・最後の記事にたどり着いた際、おかしな挙動になりますよね…
すみません、私の知識ではこの程度しか考えられません。
なんとなくレベルがわかっていただけるとうれしいです。
No.1
- 回答日時:
まずもって
・各記事をどう保存しているのか
を書いてくれないことには話にならない.
あと, 「何らかの理由で記事を消した場合」にどうするのか (記事NO が 4 の記事を消した場合, 記事NO 3 の記事の「前」と「次」はそれぞれ何になるのか) も明確にしておく必要がある.
ついでに:
$no =5; (現在の記事NO。数字が入ります)
$new_no = $no--;
$old_no = $no++;
で $no, $new_no と $old_no の値がそれぞれ何になるかわかりますか?
$no =5;
open(IN,"$logfile") || &error("Open Error : $logfile");
while (<IN>) {
($no,$year1,$month1,$day1,$name,$tail1,$W1,$H1,$item1,$item2,$item3,$item4,$item5,$host) = split(/<>/);
# 以下略
}
とやると最初の
$no =5;
の意味がなくなってしまうことは理解できていますよね?
この回答への補足
すみません色々抜けてました。
>各記事をどう保存しているのか
datファイルに$no,$year1,$month1,$day1,$name,~
の順で、"<>"で区切って保存しています。
(open~while~の部分で理解していただけると思ったので記入したのですが、書き方が間違っていたでしょうか…)
>記事NO が 4 の記事を消した場合, 記事NO 3 の記事の「前」と「次」はそれぞれ何になるのか
4を消した場合、3の記事の場合は5と2の記事に行くようにしたいです。
>no =5;の意味がなくなってしまう
すみません書き間違えです。
ページを表示するのはvnoですね。
~news.cgi?vno=5
で5記事目を表示します。
またそれぞれ
$new_no = $vno--;
$old_no = $vno++;
です。
私のスキルでは、
ログファイル開く→現ページを確認→それに+1と-1した数字を作る→whileでヒットしたところを表示、としかできません。
それをどうにかして「ログの前後の記事を表示させる」としたいです。
引き続きよろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- Excel(エクセル) vba シート名の一覧を2列に分けるには 5 2023/04/24 08:56
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- PHP コメント機能に返信欄を矢印で追加したい 1 2022/05/09 21:17
- 英語 不定代名詞"no..."の否定語noの及び範囲について 4 2022/08/04 11:11
- Visual Basic(VBA) VBAで、1つのエクセルで、2つのシートからもう1つのシートに条件のある転記コードを教えてください。 1 2023/03/16 18:07
- 英語 提示文で複合関係代名詞を繰り返さない理由の有無について 7 2022/11/21 12:32
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- Word(ワード) ワード2023でテキストボックス内の数字が勝手に変わってしまう 1 2023/02/09 14:47
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・【お題】甲子園での思い出の残し方
- ・【お題】動物のキャッチフレーズ
- ・人生で一番思い出に残ってる靴
- ・これ何て呼びますか Part2
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・あなたが好きな本屋さんを教えてください
- ・かっこよく答えてください!!
- ・一回も披露したことのない豆知識
- ・ショボ短歌会
- ・いちばん失敗した人決定戦
- ・性格悪い人が優勝
- ・最速怪談選手権
- ・限定しりとり
- ・性格いい人が優勝
- ・これ何て呼びますか
- ・チョコミントアイス
- ・単二電池
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・泣きながら食べたご飯の思い出
- ・一番好きなみそ汁の具材は?
- ・人生で一番お金がなかったとき
- ・カラオケの鉄板ソング
- ・自分用のお土産
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「型が一致しません」のエラー...
-
日齢計算プログラム
-
前日の日付取得するには?
-
Perlの日付の比較に関して
-
関数について
-
日付の差分の求め方(日、分)
-
perlでcheckboxがうまく整理で...
-
JSONで文字列が長い時
-
Application.ScreenUpdating = ...
-
メモリをアドレスを直接指定し...
-
formで特定のinputを送信しない...
-
複数列を持ったリストボックス...
-
テーブル内でドロップダウンメ...
-
VB6で、長い時間かかる処理...
-
セレクトメニューで2つの項目...
-
[python] 文字列を変数名として...
-
16進の10進変換について
-
selectタグ内の特定のoptionの...
-
FindFirst を複数条件で検索
-
構造体の各データの表示につい...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
日付の差分の求め方(日、分)
-
前日の日付取得するには?
-
1桁の日付に0を付ける
-
日齢計算プログラム
-
「型が一致しません」のエラー...
-
Perlで日付を取得する
-
Cookieの有効期限について
-
Perlの日付の比較に関して
-
CSV読み込み時に条件に合う行(...
-
年月日の数値化?
-
日付の比較について
-
質問
-
月見る月はこの月の月
-
このソースがコンパイルエラー...
-
CGI:Cookie保存期限の指定について
-
perlでcheckboxがうまく整理で...
-
JSONで文字列が長い時
-
Application.ScreenUpdating = ...
-
16進の10進変換について
-
<SELECT>タグの折り返し
おすすめ情報